<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<script type="text/javascript">
var version = {major: 1, minor: 2, revision: 34, date: new Date("Sep 28, 2005"), extensions: {}};
</script>
<!--
TiddlyWiki 1.2.34 by Jeremy Ruston, (jeremy [at] osmosoft [dot] com)

Published under a BSD open source license

Copyright (c) Osmosoft Limited 2005

Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:

Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.

Redistributions in binary form must reproduce the above copyright notice, this
list of conditions and the following disclaimer in the documentation and/or other
materials provided with the distribution.

Neither the name of the Osmosoft Limited nor the names of its contributors may be
used to endorse or promote products derived from this software without specific
prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
-->
<html>
<head>
<meta http-equiv="Content-Type" content="text/html;charset=utf-8" >
<title>TiddlyWiki - a reusable non-linear personal web notebook</title>
<script type="text/javascript">

// ---------------------------------------------------------------------------------
// Configuration repository
// ---------------------------------------------------------------------------------

var config = {
	// Options that can be set in the options panel and/or cookies
	options: {
		chkRegExpSearch: false,
		chkCaseSensitiveSearch: false,
		chkAnimate: true,
		txtUserName: "YourName",
		chkSaveBackups: true,
		chkAutoSave: false,
		chkGenerateAnRssFeed: false,
		chkSaveEmptyTemplate: false,
		chkOpenInNewWindow: true,
		chkToggleLinks: false,
		chkHttpReadOnly: false,
		chkForceMinorUpdate: false,
		txtMainTab: "tabTimeline",
		txtMoreTab: "moreTabAll"
		},
	// List of notification functions to be called when certain tiddlers are changed or deleted
	notifyTiddlers: [
		{name: "StyleSheet", notify: refreshStyles},
		{name: null, notify: refreshMenu},
		{name: null, notify: refreshStory},
		{name: null, notify: refreshTabs},
		{name: "SiteTitle", notify: refreshTitle},
		{name: "SiteSubtitle", notify: refreshSubtitle},
		{name: "SideBarOptions", notify: refreshSidebar}
		],
	// Shadow tiddlers for emergencies
	shadowTiddlers: {
		SideBarOptions: "<<gradient vert #ffffff #cc9900>><<search>><<closeAll>><<permaview>><<saveChanges>><<slider chkSliderOptionsPanel OptionsPanel настройки 'Различные настройки'>>>>",
		OptionsPanel: "Эти опции TiddlyWiki будут сохранены в браузере. \n\n Ваше имя, которым будут подписаны все записи. Используйте WikiWord (например ИванПетров) \n\n<<option txtUserName>>\n<<option chkSaveBackups>> Сохранять бэкапы\n<<option chkAutoSave>> Автосохранение\n<<option chkGenerateAnRssFeed>> Создавать RSS-ленту\n<<option chkRegExpSearch>> Поиск с Регэкспами\n<<option chkCaseSensitiveSearch>> Регистрозависимый поиск \n<<option chkAnimate>> Разрешить анимацию\n\nОткрыть AdvancedOptions",
		AdvancedOptions: "<<option chkOpenInNewWindow>> OpenLinksInNewWindow\n<<option chkSaveEmptyTemplate>> SaveEmptyTemplate\n<<option chkToggleLinks>> Clicking on links to tiddlers that are already open causes them to close\n^^(override with Control or other modifier key)^^\n<<option chkHttpReadOnly>> HideEditingFeatures when viewed over HTTP\n<<option chkForceMinorUpdate>> Treat edits as MinorChanges by preserving date and time\n^^(override with Shift key when clicking 'done' or by pressing Ctrl-Shift-Enter^^",
		SideBarTabs: "<<tabs txtMainTab История 'Записки в хронологическом порядке' TabTimeline Все 'Все записки' TabAll Тэги 'Все тэги' TabTags Еще 'Еще...' TabMore>>",
		TabTimeline: "<<timeline>>",
		TabAll: "<<list all>>",
		TabTags: "<<allTags>>",
		TabMore: "<<tabs txtMoreTab Пустые 'Не созданные записки' TabMoreMissing Одиночки 'Записки, на которые никто не ссылается' TabMoreOrphans>>",
		TabMoreMissing: "<<list missing>>",
		TabMoreOrphans: "<<list orphans>>"
		},
	// Miscellaneous options
	numRssItems: 20, // Number of items in the RSS feed
	animFast: 0.12, // Speed for animations (lower == slower)
	animSlow: 0.01, // Speed for EasterEgg animations
	// Messages
	messages: {
		customConfigError: "Ошибка в customConfig - %0",
		savedSnapshotError: "Похоже, файл с TiddlyWiki был некорректно сохранен.За разъяснениями обратитесь к http://www.tiddlywiki.com/#DownloadSoftware",
		subtitleUnknown: "(неизвестный)",
		undefinedTiddlerToolTip: "Записка '%0' еще не существует",
		externalLinkTooltip: "Внешняя ссылка на %0",
		noTags: "Нет помеченных записок",
		notFileUrlError: "Вам необходимо сохранить TiddlyWiki в файл перед сохранением изменений",
		cantSaveError: "Невозможно сохранить изменения с помощью данного браузера. Попробуйте воспользоваться FireFox.",
		invalidFileError: "Файл '%0' не является файлом TiddlyWiki",
		backupSaved: "Бэкап сохранен",
		backupFailed: "Не могу сохранить бэкап",
		rssSaved: "RSS-лента сохранена",
		rssFailed: "Не могу сохранить файл с RSS-лентой",
		emptySaved: "Пустой шаблон сохранен",
		emptyFailed: "Невозможно сохранить файл с пустым шаблоном",
		mainSaved: "Файл TiddlyWiki сохранен",
		mainFailed: "Не могу сохранить файл TiddlyWiki. Изменения не будут сохранены",
		macroError: "Ошибка выполнения макроса '%0'",
		overwriteWarning: "Записка с именем '%0' уже существует. Выберите OK для перезаписи",
		unsavedChangesWarning: "ВНИМАНИЕ! В файле TiddlyWiki есть несохраненные изменения!\n\nНажмите OK для сохранения\nНажмите CANCEL для отмены",
		dates: {
			months: ["Январь", "февраль", "Март", "Апрель", "Май", "Июнь", "Июль", "Август", "Сентябрь", "Октябрь", "Ноябрь","Декабрь"],
			days: ["Воскресенье", "Понедельник", "Вторник","Среда", "Четверг", "Суббота"]
			}
		},
	views: {
		wikified: {
			tag: {labelNoTags: "нет тэгов", labelTags: "тэги: ", tooltip: "Показать записки с тэгом '%0'", openAllText: "Открыть все записки с тэгом", openAllTooltip: "Открыть все эти записки", popupNone: "Нет других записок с тэгом '%0'"},
			toolbarClose: {text: "закрыть", tooltip: "Закрыть записку"},
			toolbarEdit: {text: "правка", tooltip: "Редактировать записку"},
			toolbarPermalink: {text: "адрес", tooltip: "Постоянная ссылка на эту записку"},
			toolbarReferences: {text: "ссылки", tooltip: "Показать записки, ссылающиеся на эту", popupNone: "Ни одна записка на эту не ссылается"},
			defaultText: "Записка '%0' еще не существует. Двойной щелчок мышью создаст ее."
			},
		editor: {
			tagPrompt: "Введите тэги, разделяя их пробелами, [[используя такие двойные скобки]] если необходимо, или добавьте существующие",
			tagChooser: {text: "тэги", tooltip: "Выберите существующие тэги для добавления к этой записке", popupNone: "Тэги не определены", tagTooltip: "Добавить тэг '%0'"},
			toolbarDone: {text: "сохранить", tooltip: "Сохранить изменения в записке"},
			toolbarCancel: {text: "отмена", tooltip: "Отменить изменения в записке"},
			toolbarDelete: {text: "удалить", tooltip: "Удалить записку"},
			defaultText: "Введите текст для '%0'"
			}
		},
	macros: { // Each has a 'handler' member that is inserted later
		today: {},
		version: {},
		search: {label: "поиск", prompt: "поиск по всем запискам", sizeTextbox: 15, accessKey: "F", successMsg: "%0 записок найдено по запросу %1", failureMsg: "Не найдено записок, удовлетворяющих запросу %0"},
		tiddler: {},
		tag: {},
		timeline: {dateFormat: "DD MMM YYYY"},
		allTags: {tooltip: "Показать записки, помеченные как '%0'", noTags: "Нет помеченых записок"},
		list: {
			all: {prompt: "Все записки по алфавиту"},
			missing: {prompt: "Ссылки без записок"},
			orphans: {prompt: "Записки без ссылок на них"}
			},
		closeAll: {label: "закрыть все", prompt: "Закрыть все записки кроме редактируемых"},
		permaview: {label: "постоянный адрес", prompt: "Линк на URL, показывающий все открытые сейчас записки"},
		saveChanges: {label: "сохранить", prompt: "Сохранить все изменения", accessKey: "S"},
		slider: {},
		option: {},
		newTiddler: {label: "новая записка", prompt: "Создать новую записку", title: "Новая", accessKey: "N"},
		newJournal: {label: "записка 'сегодня'", prompt: "Создать записку с заголовком, содержащим сегодняшнюю дату", accessKey: "J"},
		sparkline: {},
		tabs: {},
		gradient: {}
		},
	textPrimitives: {}
};

config.textPrimitives.upperLetter = "[A-ZА-Я\u00c0-\u00de\u0150\u0170]";
config.textPrimitives.lowerLetter = "[a-zа-я\u00df-\u00ff_0-9\\-\u0151\u0171]";
config.textPrimitives.anyLetter = "[A-Za-zА-Яа-я\u00c0-\u00de\u00df-\u00ff_0-9\\-\u0150\u0170\u0151\u0171]";
config.textPrimitives.anyDigit = "[0-9]";
config.textPrimitives.anyNumberChar = "[0-9\\.E]";
config.textPrimitives.urlPattern = "(?:http|https|mailto|ftp):[^\\s'\"]+(?:/|\\b)";
config.textPrimitives.unWikiLink = "~";
config.textPrimitives.wikiLink = "(?:" + config.textPrimitives.unWikiLink + "?)(?:" + config.textPrimitives.upperLetter + "+" +
											   config.textPrimitives.lowerLetter + "+" +
											   config.textPrimitives.upperLetter +
											   config.textPrimitives.anyLetter + "*)|(?:" +
											   config.textPrimitives.upperLetter + "{2,}" +
											   config.textPrimitives.lowerLetter + "+)";

// ---------------------------------------------------------------------------------
// Main
// ---------------------------------------------------------------------------------

// TiddlyWiki storage
var store = new TiddlyWiki();

// Animation engine
var anim = new Animator();

var readOnly = false;

// Starting up
function main()
{
	readOnly = (document.location.toString().substr(0,7) == "http://") ? config.options.chkHttpReadOnly : false;
	saveTest();
	loadOptionsCookie();
	for(var s=0; s<config.notifyTiddlers.length; s++)
		store.addNotification(config.notifyTiddlers[s].name,config.notifyTiddlers[s].notify);
	store.loadFromDiv("storeArea","store");
	loadSystemConfig();
	store.notifyAll();
	restart();
}

// Restarting
function restart()
{
	var start = store.getTiddlerText("DefaultTiddlers");
	if(window.location.hash)
		displayTiddlers(null,convertUTF8ToUnicode(decodeURI(window.location.hash.substr(1))),1,null,null);
	else if(start)
		displayTiddlers(null,start,1,null,null);
}

function saveTest()
{
	var saveTest = document.getElementById("saveTest");
	if(saveTest.hasChildNodes())
		alert(config.messages.savedSnapshotError);
	saveTest.appendChild(document.createTextNode("savetest"));
}

function loadSystemConfig()
{
	var configTiddlers = store.getTaggedTiddlers("systemConfig");
	for(var t=0; t<configTiddlers.length; t++)
		{
		var ex = processConfig(configTiddlers[t].text);
		if(ex)
			displayMessage(config.messages.customConfigError.format([ex]));
		}
}

// Merge a custom configuration over the top of the current configuration
// Returns a string error message or null if it went OK
function processConfig(customConfig)
{
	try
		{
		if(customConfig && customConfig != "")
			window.eval(customConfig);
		}
	catch(e)
		{
		return(e.toString());
		}
	return null;
}

// ---------------------------------------------------------------------------------
// Formatters
// ---------------------------------------------------------------------------------

config.formatterHelpers = {

	charFormatHelper: function(w)
	{
		var e = createTiddlyElement(w.output,this.element);
		w.subWikify(e,this.terminator);
	},
	
	inlineCssHelper:  function(w)
	{
		var styles = [];
		var lookahead = "(?:(" + config.textPrimitives.anyLetter + "+)\\(([^\\)\\|\\n]+)(?:\\):))|(?:(" + config.textPrimitives.anyLetter + "+):([^;\\|\\n]+);)";
		var lookaheadRegExp = new RegExp(lookahead,"mg");
		var hadStyle = false;
		do {
			lookaheadRegExp.lastIndex = w.nextMatch;
			var lookaheadMatch = lookaheadRegExp.exec(w.source);
			var gotMatch = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
			if(gotMatch)
				{
				var s,v;
				hadStyle = true;
				if(lookaheadMatch[1])
					{
					s = lookaheadMatch[1].unDash();
					v = lookaheadMatch[2];
					}
				else
					{
					s = lookaheadMatch[3].unDash();
					v = lookaheadMatch[4];
					}
				switch(s)
					{
					case "bgcolor": s = "backgroundColor"; break;
					}
				styles.push({style: s, value: v});
				w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
				}
		} while(gotMatch);
		return styles;
	}

};

config.formatters = [
{
	name: "table",
	match: "^\\|(?:[^\\n]*)\\|(?:[fhc]?)$",
	lookahead: "^\\|([^\\n]*)\\|([fhc]?)$",
	rowTerminator: "\\|(?:[fhc]?)$\\n?",
	cellPattern: "(?:\\|([^\\n\\|]*)\\|)|(\\|[fhc]?$\\n?)",
	cellTerminator: "(?:\\x20*)\\|",
	rowTypes: {"c": "caption", "h": "thead", "": "tbody", "f": "tfoot"},
	handler: function(w)
	{
		var table = createTiddlyElement(w.output,"table");
		w.nextMatch = w.matchStart;
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		var currRowType = null, nextRowType;
		var rowContainer, rowElement;
		var prevColumns = [];
		var rowCount = 0;
		do {
			lookaheadRegExp.lastIndex = w.nextMatch;
			var lookaheadMatch = lookaheadRegExp.exec(w.source);
			var matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
			if(matched)
				{
				nextRowType = lookaheadMatch[2];
				if(nextRowType != currRowType)
					rowContainer = createTiddlyElement(table,this.rowTypes[nextRowType]);
				currRowType = nextRowType;
				if(currRowType == "c")
					{
					if(rowCount == 0)
						rowContainer.setAttribute("align","top");
					else
						rowContainer.setAttribute("align","bottom");
					w.nextMatch = w.nextMatch + 1;
					w.subWikify(rowContainer,this.rowTerminator);
					}
				else
					{
					rowElement = createTiddlyElement(rowContainer,"tr");
					this.rowHandler(w,rowElement,prevColumns);
					}
				rowCount++;
				}
		} while(matched);
	},
	rowHandler: function(w,e,prevColumns)
	{
		var col = 0;
		var currColCount = 1;
		var cellRegExp = new RegExp(this.cellPattern,"mg");
		do {
			cellRegExp.lastIndex = w.nextMatch;
			var cellMatch = cellRegExp.exec(w.source);
			matched = cellMatch && cellMatch.index == w.nextMatch;
			if(matched)
				{
				if(cellMatch[1] == "~")
					{
					var last = prevColumns[col];
					if(last)
						{
						last.rowCount++;
						last.element.setAttribute("rowSpan",last.rowCount);
						last.element.setAttribute("rowspan",last.rowCount);
						last.element.valign = "center";
						}
					w.nextMatch = cellMatch.index + cellMatch[0].length-1;
					}
				else if(cellMatch[1] == ">")
					{
					currColCount++;
					w.nextMatch = cellMatch.index + cellMatch[0].length-1;
					}
				else if(cellMatch[2])
					{
					w.nextMatch = cellMatch.index + cellMatch[0].length;;
					break;
					}
				else
					{
					var spaceLeft = false, spaceRight = false;
					w.nextMatch++;
					var styles = config.formatterHelpers.inlineCssHelper(w);
					while(w.source.substr(w.nextMatch,1) == " ")
						{
						spaceLeft = true;
						w.nextMatch++;
						}
					var cell;
					if(w.source.substr(w.nextMatch,1) == "!")
						{
						cell = createTiddlyElement(e,"th");
						w.nextMatch++;
						}
					else
						cell = createTiddlyElement(e,"td");
					prevColumns[col] = {rowCount: 1, element: cell};
					lastColCount = 1;
					lastColElement = cell;
					if(currColCount > 1)
						{
						cell.setAttribute("colSpan",currColCount);
						cell.setAttribute("colspan",currColCount);
						currColCount = 1;
						}
					for(var t=0; t<styles.length; t++)
						cell.style[styles[t].style] = styles[t].value;
					w.subWikify(cell,this.cellTerminator);
					if(w.matchText.substr(w.matchText.length-2,1) == " ")
						spaceRight = true;
					if(spaceLeft && spaceRight)
						cell.align = "center";
					else if (spaceLeft)
						cell.align = "right";
					else if (spaceRight)
						cell.align = "left";
					w.nextMatch = w.nextMatch-1;
					}
				col++;
				}
		} while(matched);		
	}
},

{
	name: "rule",
	match: "^----$\\n?",
	handler: function(w)
	{
		createTiddlyElement(w.output,"hr");
	}
},

{
	name: "heading",
	match: "^!{1,5}",
	terminator: "\\n",
	handler: function(w)
	{
		var e = createTiddlyElement(w.output,"h" + w.matchLength);
		w.subWikify(e,this.terminator);
	}
},

{
	name: "monospacedByLine",
	match: "^\\{\\{\\{\\n",
	lookahead: "^\\{\\{\\{\\n((?:^[^\\n]*\\n)+?)(^\\}\\}\\}$\\n?)",
	handler: function(w)
	{
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
			{
			var text = lookaheadMatch[1].replace(/\n/g,"\r\n");
			var e = createTiddlyElement(w.output,"pre",null,null,text);
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
			}
	}
},

{
	name: "quoteByBlock",
	match: "^<<<\\n",
	terminator: "^<<<\\n",
	handler: function(w)
	{
		var e = createTiddlyElement(w.output,"blockquote");
		w.subWikify(e,this.terminator);
	}
},

{
	name: "quoteByLine",
	match: "^>+",
	terminator: "\\n",
	element: "blockquote",
	handler: function(w)
	{
		var lookaheadRegExp = new RegExp(this.match,"mg");
		var placeStack = [w.output];
		var currLevel = 0;
		var newLevel = w.matchLength;
		var t;
		do {
			if(newLevel > currLevel)
				{
				for(t=currLevel; t<newLevel; t++)
					placeStack.push(createTiddlyElement(placeStack[placeStack.length-1],this.element));
				}
			else if(newLevel < currLevel)
				{
				for(t=currLevel; t>newLevel; t--)
					placeStack.pop();
				}
			currLevel = newLevel;
			w.subWikify(placeStack[placeStack.length-1],this.terminator);
			createTiddlyElement(placeStack[placeStack.length-1],"br");
			lookaheadRegExp.lastIndex = w.nextMatch;
			var lookaheadMatch = lookaheadRegExp.exec(w.source);
			var matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
			if(matched)
				{
				newLevel = lookaheadMatch[0].length;
				w.nextMatch += lookaheadMatch[0].length;
				}
		} while(matched);
	}
},

{
	name: "list",
	match: "^(?:(?:\\*+)|(?:#+)|(?:№+))",
	lookahead: "^(?:(\\*+)|(#+)|(№+))",
	terminator: "\\n",
	outerElement: "ul",
	itemElement: "li",
	handler: function(w)
	{
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		w.nextMatch = w.matchStart;
		var placeStack = [w.output];
		var currType = null, newType;
		var currLevel = 0, newLevel;
		var t;
		do {
			lookaheadRegExp.lastIndex = w.nextMatch;
			var lookaheadMatch = lookaheadRegExp.exec(w.source);
			var matched = lookaheadMatch && lookaheadMatch.index == w.nextMatch;
			if(matched)
				{
				if(lookaheadMatch[1])
					newType = "ul";
				if(lookaheadMatch[2]||lookaheadMatch[3])
					newType = "ol";
				newLevel = lookaheadMatch[0].length;
				w.nextMatch += lookaheadMatch[0].length;
				if(newLevel > currLevel)
					{
					for(t=currLevel; t<newLevel; t++)
						placeStack.push(createTiddlyElement(placeStack[placeStack.length-1],newType));
					}
				else if(newLevel < currLevel)
					{
					for(t=currLevel; t>newLevel; t--)
						placeStack.pop();
					}
				else if(newLevel == currLevel && newType != currType)
					{
						placeStack.pop();
						placeStack.push(createTiddlyElement(placeStack[placeStack.length-1],newType));
					}
				currLevel = newLevel;
				currType = newType;
				var e = createTiddlyElement(placeStack[placeStack.length-1],"li");
				w.subWikify(e,this.terminator);
				}
		} while(matched);
	}
},

{
	name: "wikiLink",
	match: config.textPrimitives.wikiLink,
	handler: function(w)
	{
		if(w.matchText.substr(0,1) == config.textPrimitives.unWikiLink)
			{
			w.outputText(w.output,w.matchStart + 1,w.nextMatch);
			}
		else
			{
			var link = createTiddlyLink(w.output,w.matchText,false);
			w.outputText(link,w.matchStart,w.nextMatch);
			}
	}
},

{
	name: "prettyLink",
	match: "\\[\\[",
	lookahead: "\\[\\[([^\\|\\]]*?)(?:(\\]\\])|(\\|(.*?)\\]\\]))",
	terminator: "\\|",
	handler: function(w)
	{
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[2]) // Simple bracketted link
			{
			var link = createTiddlyLink(w.output,lookaheadMatch[1],false);
			w.outputText(link,w.nextMatch,w.nextMatch + lookaheadMatch[1].length);
			w.nextMatch += lookaheadMatch[1].length + 2;
			}
		else if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[3]) // Pretty bracketted link
			{
			var e;
			if(store.tiddlerExists(lookaheadMatch[4]))
				e = createTiddlyLink(w.output,lookaheadMatch[4],false);
			else
				e = createExternalLink(w.output,lookaheadMatch[4]);
			w.outputText(e,w.nextMatch,w.nextMatch + lookaheadMatch[1].length);
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
			}
	}
},

{
	name: "prettyLinkRU",
	match: "\\(-",
	lookahead: "\\(-([^\\|\\]]*?)(?:(-\\))|(\\|(.*?)-\\)))",
	terminator: "\\|",
	handler: function(w)
	{
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[2]) // Simple bracketted link
			{
			var link = createTiddlyLink(w.output,lookaheadMatch[1],false);
			w.outputText(link,w.nextMatch,w.nextMatch + lookaheadMatch[1].length);
			w.nextMatch += lookaheadMatch[1].length + 2;
			}
		else if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[3]) // Pretty bracketted link
			{
			var e;
			if(store.tiddlerExists(lookaheadMatch[4]))
				e = createTiddlyLink(w.output,lookaheadMatch[4],false);
			else
				e = createExternalLink(w.output,lookaheadMatch[4]);
			w.outputText(e,w.nextMatch,w.nextMatch + lookaheadMatch[1].length);
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
			}
	}
},

{
	name: "urlLink",
	match: "(?:http|https|mailto|ftp):[^\\s'\"]+(?:/|\\b)",
	handler: function(w)
	{
		var e = createExternalLink(w.output,w.matchText);
		w.outputText(e,w.matchStart,w.nextMatch);
	}
},

{
	name: "image",
	match: "\\[(?:[<]{0,1})(?:[>]{0,1})[Ii][Mm][Gg]\\[",
	lookahead: "\\[([<]{0,1})([>]{0,1})[Ii][Mm][Gg]\\[(?:([^\\|]+)\\|)?([^\\[\\]\\|]+)\\](?:\\[([^\\]]*)\\]?)?\\]",
	handler: function(w)
	{
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = lookaheadRegExp.exec(w.source);
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart) // Simple bracketted link
			{
			var e = w.output;
			if(lookaheadMatch[5])
				{
				if(store.tiddlerExists(lookaheadMatch[5]))
					e = createTiddlyLink(w.output,lookaheadMatch[5],false);
				else
					e = createExternalLink(w.output,lookaheadMatch[5]);
				}
			var img = createTiddlyElement(e,"img");
			if(lookaheadMatch[1])
				img.align = "left";
			else if(lookaheadMatch[2])
				img.align = "right";
			if(lookaheadMatch[3])
				img.title = lookaheadMatch[3];
			img.src = lookaheadMatch[4];
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
			}
	}
},

{
	name: "macro",
	match: "<<",
	lookahead: "<<([^>\\s]+)(?:\\s*)([^>]*)>>",
	handler: function(w)
	{
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart && lookaheadMatch[1])
			{
			var params = lookaheadMatch[2].readMacroParams();			
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
			try
				{
				var macro = config.macros[lookaheadMatch[1]];
				if(macro && macro.handler)
					macro.handler(w.output,lookaheadMatch[1],params,w);
				else
					createTiddlyElement(w.output,"span",null,"errorNoSuchMacro","<<" + lookaheadMatch[1] + ">>");
				}
			catch(e)
				{
				displayMessage(config.messages.macroError.format([lookaheadMatch[1]]));
				displayMessage(e.toString());
				}
			}
	}
},

{
	name: "html",
	match: "<[Hh][Tt][Mm][Ll]>",
	lookahead: "<[Hh][Tt][Mm][Ll]>((?:.|\\n)*?)</[Hh][Tt][Mm][Ll]>",
	handler: function(w)
	{
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
			{
			var e = createTiddlyElement(w.output,"span");
			e.innerHTML = lookaheadMatch[1];
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
			}
	}
},

{
	name: "boldByChar",
	match: "''",
	terminator: "''",
	element: "strong",
	handler: config.formatterHelpers.charFormatHelper
},

{
	name: "boldByCharRU",
	match: "\\+\\+",
	terminator: "\\+\\+",
	element: "strong",
	handler: config.formatterHelpers.charFormatHelper
},

{
	name: "strikeByChar",
	match: "==",
	terminator: "==",
	element: "strike",
	handler: config.formatterHelpers.charFormatHelper
},

{
	name: "underlineByChar",
	match: "__",
	terminator: "__",
	element: "u",
	handler: config.formatterHelpers.charFormatHelper
},

{
	name: "italicByChar",
	match: "//",
	terminator: "//",
	element: "em",
	handler: config.formatterHelpers.charFormatHelper
},

{
	name: "subscriptByChar",
	match: "~~",
	terminator: "~~",
	element: "sub",
	handler: config.formatterHelpers.charFormatHelper
},

{
	name: "superscriptByChar",
	match: "\\^\\^",
	terminator: "\\^\\^",
	element: "sup",
	handler: config.formatterHelpers.charFormatHelper
},

{
	name: "monospacedByChar",
	match: "\\{\\{\\{",
	lookahead: "\\{\\{\\{((?:.|\\n)*?)\\}\\}\\}",
	handler: function(w)
	{
		var lookaheadRegExp = new RegExp(this.lookahead,"mg");
		lookaheadRegExp.lastIndex = w.matchStart;
		var lookaheadMatch = lookaheadRegExp.exec(w.source)
		if(lookaheadMatch && lookaheadMatch.index == w.matchStart)
			{
			var e = createTiddlyElement(w.output,"code",null,null,lookaheadMatch[1]);
			w.nextMatch = lookaheadMatch.index + lookaheadMatch[0].length;
			}
	}
},

{
	name: "styleByChar",
	match: "@@",
	terminator: "@@",
	lookahead: "(?:([^\\(@]+)\\(([^\\)]+)(?:\\):))|(?:([^:@]+):([^;]+);)",
	handler:  function(w)
	{
		var e = createTiddlyElement(w.output,"span",null,null,null);
		var styles = config.formatterHelpers.inlineCssHelper(w);
		if(styles.length == 0)
			e.className = "marked";
		else
			for(var t=0; t<styles.length; t++)
				e.style[styles[t].style] = styles[t].value;
		w.subWikify(e,this.terminator);
	}
},

{
	name: "lineBreak",
	match: "\\n",
	handler: function(w)
	{
		createTiddlyElement(w.output,"br");
	}
}
];

// ---------------------------------------------------------------------------------
// Wikifier
// ---------------------------------------------------------------------------------

function wikify(source,output,highlightText,highlightCaseSensitive)
{
	var w = new Wikifier(source,output,config.formatters,highlightText,highlightCaseSensitive);
}

function Wikifier(source,output,formatters,highlightText,highlightCaseSensitive)
{
	this.source = source;
	this.output = output;
	this.formatters = formatters;
	this.formatterRegExp = this.assembleFormatterMatches(formatters);
	this.nextMatch = 0;
	this.highlightText = highlightText;
	this.highlightCaseSensitive = highlightCaseSensitive;
	this.highlightRegExp = null;
	this.highlightMatch = null;
	if(highlightText)
		{
		this.highlightRegExp = new RegExp(highlightText,highlightCaseSensitive ? "mg" : "img");
		this.highlightMatch = this.highlightRegExp.exec(this.source);
		}
	this.subWikify(output,null);
	return this;
}

Wikifier.prototype.assembleFormatterMatches = function(formatters)
{
	var pattern = [];
	for(var n=0; n<formatters.length; n++)
		pattern.push("(" + formatters[n].match + ")");
	return new RegExp(pattern.join("|"),"mg");
}

Wikifier.prototype.subWikify = function(output,terminator)
{
	// Temporarily replace the output pointer
	var oldOutput = this.output;
	this.output = output;
	// Prepare the terminator RegExp
	var terminatorRegExp = terminator ? new RegExp("(" + terminator + ")","mg") : null;
	do {
		// Prepare the RegExp match positions
		this.formatterRegExp.lastIndex = this.nextMatch;
		if(terminatorRegExp)
			terminatorRegExp.lastIndex = this.nextMatch;
		// Get the first matches
		var formatterMatch = this.formatterRegExp.exec(this.source);
		var terminatorMatch = terminatorRegExp ? terminatorRegExp.exec(this.source) : null;
		// Check for a terminator match
		if(terminatorMatch && (!formatterMatch || terminatorMatch.index <= formatterMatch.index))
			{
			// Output any text before the match
			if(terminatorMatch.index > this.nextMatch)
				this.outputText(this.output,this.nextMatch,terminatorMatch.index);
			// Set the match parameters
			this.matchStart = terminatorMatch.index;
			this.matchLength = terminatorMatch[1].length;
			this.matchText = terminatorMatch[1];
			this.nextMatch = terminatorMatch.index + terminatorMatch[1].length;
			// Restore the output pointer and exit
			this.output = oldOutput;
			return;		
			}
		// Check for a formatter match
		else if(formatterMatch)
			{
			// Output any text before the match
			if(formatterMatch.index > this.nextMatch)
				this.outputText(this.output,this.nextMatch,formatterMatch.index);
			// Set the match parameters
			this.matchStart = formatterMatch.index;
			this.matchLength = formatterMatch[0].length;
			this.matchText = formatterMatch[0];
			this.nextMatch = this.formatterRegExp.lastIndex;
			// Figure out which formatter matched
			var matchingformatter = -1;
			for(var t=1; t<formatterMatch.length; t++)
				if(formatterMatch[t])
					matchingFormatter = t-1;
			// Call the formatter
			if(matchingFormatter != -1)
				this.formatters[matchingFormatter].handler(this);
			}
	} while(terminatorMatch || formatterMatch);
	// Output any text after the last match
	if(this.nextMatch < this.source.length)
		{
		this.outputText(this.output,this.nextMatch,this.source.length);
		this.nextMatch = this.source.length;
		}
	// Restore the output pointer
	this.output = oldOutput;
}

Wikifier.prototype.outputText = function(place,startPos,endPos)
{
	// Check for highlights
	while(this.highlightMatch && (this.highlightRegExp.lastIndex > startPos) && (this.highlightMatch.index < endPos) && (startPos < endPos))
		{
		// Deal with any plain text before the highlight
		if(this.highlightMatch.index > startPos)
			{
			createTiddlyText(place,this.source.substring(startPos,this.highlightMatch.index));
			startPos = this.highlightMatch.index;
			}
		// Deal with the highlight
		var highlightEnd = Math.min(this.highlightRegExp.lastIndex,endPos);
		var theHighlight = createTiddlyElement(place,"span",null,"highlight",this.source.substring(startPos,highlightEnd));
		startPos = highlightEnd;
		// Nudge along to the next highlight if we're done with this one
		if(startPos >= this.highlightRegExp.lastIndex)
			this.highlightMatch = this.highlightRegExp.exec(this.source);
		}
	// Do the unhighlighted text left over
	if(startPos < endPos)
		{
		createTiddlyText(place,this.source.substring(startPos,endPos));
		}
}

// ---------------------------------------------------------------------------------
// Macro definitions
// ---------------------------------------------------------------------------------

config.macros.today.handler = function(place)
{
	createTiddlyElement(place,"span",null,null,(new Date()).toLocaleString());
}

config.macros.version.handler = function(place)
{
	createTiddlyElement(place,"span",null,null,version.major + "." + version.minor + "." + version.revision);
}

config.macros.list.handler = function(place,macroName,params)
{
	var type = params[0] ? params[0] : "all";
	var theList = document.createElement("ul");
	place.appendChild(theList);
	if(this[type].prompt)
		createTiddlyElement(theList,"li",null,"listTitle",this[type].prompt);
	var results;
	if(this[type].handler)
		results = this[type].handler(params);
	for (t = 0; t < results.length; t++)
		{
		theListItem = document.createElement("li")
		theList.appendChild(theListItem);
		if(typeof results[t] == "string")
			createTiddlyLink(theListItem,results[t],true);
		else
			createTiddlyLink(theListItem,results[t].title,true);
		}
}

config.macros.list.all.handler = function(params)
{
	return store.reverseLookup("tags","excludeLists",false,"title");
}

config.macros.list.missing.handler = function(params)
{
	return store.getMissingLinks();
}

config.macros.list.orphans.handler = function(params)
{
	return store.getOrphans();
}

config.macros.allTags.handler = function(place,macroName,params)
{
	var tags = store.getTags();
	var theDateList = createTiddlyElement(place,"ul",null,null,null);
	if(tags.length == 0)
		createTiddlyElement(theDateList,"li",null,"listTitle",this.noTags);
	for (t=0; t<tags.length; t++)
		{
		var theListItem =createTiddlyElement(theDateList,"li",null,null,null);
		var theTag = createTiddlyButton(theListItem,tags[t][0] + " (" + tags[t][1] + ")",this.tooltip.format([tags[t][0]]),onClickTag);
		theTag.setAttribute("tag",tags[t][0]);
		}
}

config.macros.timeline.handler = function(place,macroName,params)
{
	var tiddlers = store.reverseLookup("tags","excludeLists",false,"modified");
	var lastDay = "";
	for (t=tiddlers.length-1; t>=0; t--)
		{
		var tiddler = tiddlers[t];
		var theDay = tiddler.modified.convertToYYYYMMDDHHMM().substr(0,8);
		if(theDay != lastDay)
			{
			var theDateList = document.createElement("ul");
			place.appendChild(theDateList);
			createTiddlyElement(theDateList,"li",null,"listTitle",tiddler.modified.formatString(this.dateFormat));
			lastDay = theDay;
			}
		var theDateListItem = createTiddlyElement(theDateList,"li",null,"listLink",null);
		theDateListItem.appendChild(createTiddlyLink(place,tiddler.title,true));
		}
}

config.macros.search.handler = function(place,macroName,params)
{
	var lastSearchText = "";
	var searchTimeout = null;
	var doSearch = function(txt)
		{
		closeAllTiddlers();
		var matches = store.search(txt.value,config.options.chkCaseSensitiveSearch,config.options.chkRegExpSearch,"title","excludeSearch");
		for(var t=matches.length-1; t>=0; t--)
			displayTiddler(null,matches[t].title,0,txt.value,config.options.chkCaseSensitiveSearch,false,false);
		var q = config.options.chkRegExpSearch ? "/" : "'";
		if(matches.length > 0)
			displayMessage(config.macros.search.successMsg.format([matches.length.toString(),q + txt.value + q]));
		else
			displayMessage(config.macros.search.failureMsg.format([q + txt.value + q]));
		lastSearchText = txt.value;
		};
	var clickHandler = function(e)
		{
		doSearch(this.nextSibling);
		return false;
		};
	var keyHandler = function(e)
		{
		if (!e) var e = window.event;
		switch(e.keyCode)
			{
			case 27:
				this.value = "";
				clearMessage();
				break;
			}
		if((this.value.length > 2) && (this.value != lastSearchText))
			{
			if(searchTimeout)
				clearTimeout(searchTimeout);
			var txt = this;
			searchTimeout = setTimeout(function() {doSearch(txt);},200);
			}
		};
	var focusHandler = function(e)
		{
		this.select();
		};
	var btn = createTiddlyButton(place,this.label,this.prompt,clickHandler);
	var txt = createTiddlyElement(place,"input",null,null,null);
	if(params[0])
		txt.value = params[0];
	txt.onkeyup = keyHandler;
	txt.onfocus = focusHandler;
	txt.setAttribute("size",this.sizeTextbox);
	txt.setAttribute("accessKey",this.accessKey);
	txt.setAttribute("autocomplete","off");
	if(navigator.userAgent.toLowerCase().indexOf("safari") == -1)
		txt.setAttribute("type","text");
	else
		{
		txt.setAttribute("type","search");
		txt.setAttribute("results","5");
		}
}

config.macros.tiddler.handler = function(place,macroName,params)
{
	var wrapper = createTiddlyElement(place,"span",null,params[1] ? params[1] : null,null);
	var text = store.getTiddlerText(params[0]);
	if(text)
		wikify(text,wrapper);
}

config.macros.tag.handler = function(place,macroName,params)
{
	createTagButton(place,params[0]);
}

config.macros.closeAll.handler = function(place)
{
	createTiddlyButton(place,this.label,this.prompt,function () {closeAllTiddlers(); return false;});
}

config.macros.permaview.handler = function(place)
{
	createTiddlyButton(place,this.label,this.prompt,function () {onClickPermaView(); return false;});
}

config.macros.saveChanges.handler = function(place)
{
	if(!readOnly)
		createTiddlyButton(place,this.label,this.prompt,function () {saveChanges(); return false;},null,null,this.accessKey);
}

config.macros.slider.onClickSlider = function(e)
{
	if (!e) var e = window.event;
	var n = this.nextSibling;
	var cookie = n.getAttribute("cookie");
	var isOpen = n.style.display != "none";
	if(config.options.chkAnimate)
		anim.startAnimating(new Slider(n,!isOpen,e.shiftKey || e.altKey,"none"));
	else
		n.style.display = isOpen ? "none" : "block";
	config.options[cookie] = !isOpen;
	saveOptionCookie(cookie);
	return false;
}

config.macros.slider.handler = function(place,macroName,params)
{
	var cookie = params[0] ? params[0] : "";
	var text = store.getTiddlerText(params[1]);
	var btn = createTiddlyButton(place,params[2],params[3],this.onClickSlider);
	var panel = createTiddlyElement(place,"div",null,"sliderPanel",null);
	panel.setAttribute("cookie",cookie);
	panel.style.display = config.options[cookie] ? "block" : "none";
	if(text)
		wikify(text,panel);
}

config.macros.option.onChangeOption = function(e)
{
	var opt = this.getAttribute("option");
	var elementType,valueField;
	if(opt)
		{
		switch(opt.substr(0,3))
			{
			case "txt":
				elementType = "input";
				valueField = "value";
				break;
			case "chk":
				elementType = "input";
				valueField = "checked";
				break;
			}
		config.options[opt] = this[valueField];
		saveOptionCookie(opt);
		var nodes = document.getElementsByTagName(elementType);
		for(var t=0; t<nodes.length; t++)
			{
			var optNode = nodes[t].getAttribute("option");
			if(opt == optNode)
				nodes[t][valueField] = this[valueField];
			}
		}
	return(true);
}

config.macros.option.handler = function(place,macroName,params)
{
	var opt = params[0];
	if(config.options[opt] == undefined)
		return;
	var c;
	switch(opt.substr(0,3))
		{
		case "txt":
			c = document.createElement("input");
			c.onkeyup = this.onChangeOption;
			c.setAttribute("option",opt);
			c.size = 15;
			place.appendChild(c);
			c.value = config.options[opt];
			break;
		case "chk":
			c = document.createElement("input");
			c.setAttribute("type","checkbox");
			c.onclick = this.onChangeOption;
			c.setAttribute("option",opt);
			place.appendChild(c);
			c.checked = config.options[opt];
			break;
		}
}

config.macros.newTiddler.onClick = function()
{
	displayTiddler(null,config.macros.newTiddler.title,2,null,null,false,false);
	var e = document.getElementById("editorTitle" + config.macros.newTiddler.title);
	e.focus();
	e.select();
	return false;
}

config.macros.newTiddler.handler = function(place)
{
	if(!readOnly)
		createTiddlyButton(place,this.label,this.prompt,this.onClick,null,null,this.accessKey);
}

config.macros.newJournal.handler = function(place,macroName,params)
{
	if(!readOnly)
		{
		var now = new Date();
		var title = now.formatString(params[0].trim());
		var createJournal = function() {
			displayTiddler(null,title,2,null,null,false,false);
			var tagsBox = document.getElementById("editorTags" + title);
			if(tagsBox && params[1])
				tagsBox.value += " " + String.encodeTiddlyLink(params[1]);
			return false;
			};
		createTiddlyButton(place,this.label,this.prompt,createJournal,null,null,this.accessKey);
		}
}

config.macros.sparkline.handler = function(place,macroName,params)
{
	var data = [];
	var min = 0;
	var max = 0;
	for(var t=0; t<params.length; t++)
		{
		var v = parseInt(params[t]);
		if(v < min)
			min = v;
		if(v > max)
			max = v;
		data.push(v);
		}
	if(data.length < 1)
		return;
	var box = createTiddlyElement(place,"span",null,"sparkline",String.fromCharCode(160));
	box.title = data.join(",");
	var w = box.offsetWidth;
	var h = box.offsetHeight;
	box.style.paddingRight = (data.length * 2 - w) + "px";
	box.style.position = "relative";
	for(var d=0; d<data.length; d++)
		{
		var tick = document.createElement("img");
		tick.border = 0;
		tick.className = "sparktick";
		tick.style.position = "absolute";
		tick.src = "data:image/gif,GIF89a%01%00%01%00%91%FF%00%FF%FF%FF%00%00%00%C0%C0%C0%00%00%00!%F9%04%01%00%00%02%00%2C%00%00%00%00%01%00%01%00%40%02%02T%01%00%3B";
		tick.style.left = d*2 + "px";
		tick.style.width = "2px";
		var v = Math.floor(((data[d] - min)/(max-min)) * h);
		tick.style.top = (h-v) + "px";
		tick.style.height = v + "px";
		box.appendChild(tick);
		}
}

config.macros.tabs.handler = function(place,macroName,params)
{
	var cookie = params[0];
	var numTabs = (params.length-1)/3;
	var wrapper = createTiddlyElement(place,"div",null,cookie,null);
	var tabset = createTiddlyElement(wrapper,"div",null,"tabset",null);
	tabset.setAttribute("cookie",cookie);
	var validTab = false;
	for(var t=0; t<numTabs; t++)
		{
		var label = params[t*3+1];
		var prompt = params[t*3+2];
		var content = params[t*3+3];
		var tab = createTiddlyButton(tabset,label,prompt,this.onClickTab,"tab tabUnselected");
		tab.setAttribute("tab",label);
		tab.setAttribute("content",content);
		tab.title = prompt;
		if(config.options[cookie] == label)
			validTab = true;
		}
	if(!validTab)
		config.options[cookie] = params[1];
	this.switchTab(tabset,config.options[cookie]);
}

config.macros.tabs.onClickTab = function(e)
{
	config.macros.tabs.switchTab(this.parentNode,this.getAttribute("tab"));
	return false;
}

config.macros.tabs.switchTab = function(tabset,tab)
{
	var cookie = tabset.getAttribute("cookie");
	var theTab = null
	var nodes = tabset.childNodes;
	for(var t=0; t<nodes.length; t++)
		if(nodes[t].getAttribute && nodes[t].getAttribute("tab") == tab)
			{
			theTab = nodes[t];
			theTab.className = "tab tabSelected";
			}
		else
			nodes[t].className = "tab tabUnselected"
	if(theTab)
		{
		if(tabset.nextSibling && tabset.nextSibling.className == "tabContents")
			tabset.parentNode.removeChild(tabset.nextSibling);
		var tabContent = createTiddlyElement(null,"div",null,"tabContents",null);
		tabset.parentNode.insertBefore(tabContent,tabset.nextSibling);
		wikify(store.getTiddlerText(theTab.getAttribute("content")),tabContent);
		if(cookie)
			{
			config.options[cookie] = tab;
			saveOptionCookie(cookie);
			}
		}
}

// <<gradient [[tiddler name]] vert|horiz rgb rgb rgb rgb... >>
config.macros.gradient.handler = function(place,macroName,params,wikifier)
{
	var terminator = ">>";
	var panel = createTiddlyElement(place,"div",null,"gradient",null);
	panel.style.position = "relative";
	panel.style.overflow = "hidden";
	var styles = config.formatterHelpers.inlineCssHelper(wikifier);
	var t;
	for(t=0; t<styles.length; t++)
		panel.style[styles[t].style] = styles[t].value;
	var colours = [];
	for(t=1; t<params.length; t++)
		{
		var c = new RGB(params[t]);
		if(c)
			colours.push(c);
		}
	drawGradient(panel,params[0] != "vert",colours);
	wikifier.subWikify(panel,terminator);
	if(document.all)
		{
		panel.style.height = "100%";
		panel.style.width = "100%";
		}
}

// ---------------------------------------------------------------------------------
// Tiddler() object
// ---------------------------------------------------------------------------------

function Tiddler()
{
	this.title = null;
	this.text = null;
	this.modifier = null;
	this.modified = new Date();
	this.links = [];
	this.tags = [];
	return this;
}

// Load a tiddler from an HTML DIV
Tiddler.prototype.loadFromDiv = function(divRef,title)
{
	var text = Tiddler.unescapeLineBreaks(divRef.firstChild ? divRef.firstChild.nodeValue : "");
	var modifier = divRef.getAttribute("modifier");
	var modified = Date.convertFromYYYYMMDDHHMM(divRef.getAttribute("modified"));
	var tags = divRef.getAttribute("tags");
	this.set(title,text,modifier,modified,tags);
	return this;
}

// Format the text for storage in an HTML DIV
Tiddler.prototype.saveToDiv = function()
{
	return '<div tiddler="' + this.title + '" modified="' +
							this.modified.convertToYYYYMMDDHHMM() + '" modifier="' + this.modifier +
							'" tags="' + this.getTags() + '">' +
							this.escapeLineBreaks().htmlEncode() + '</div>';
}

// Format the text for storage in an RSS item
Tiddler.prototype.saveToRss = function(url)
{
	var s = [];
	s.push("<item>");
	s.push("<title>" + this.title.htmlEncode() + "</title>");
	s.push("<description>" + this.text.replace(regexpNewLine,"<br />").htmlEncode() + "</description>");
	for(var t=0; t<this.tags.length; t++)
		s.push("<category>" + this.tags[t] + "</category>");
	s.push("<link>" + url + "#" + encodeURIComponent(String.encodeTiddlyLink(this.title)) + "</link>");
	s.push("<pubDate>" + this.modified.toGMTString() + "</pubDate>");
	s.push("</item>");
	return(s.join("\n"));
}

// Change the text and other attributes of a tiddler
Tiddler.prototype.set = function(title,text,modifier,modified,tags)
{
	if(title != undefined)
		this.title = title;
	if(text != undefined)
		this.text = text;
	if(modifier != undefined)
		this.modifier = modifier;
	if(modified != undefined)
		this.modified = modified;
	if(tags != undefined)
		this.tags = (typeof tags == "string") ? tags.readBracketedList() : tags;
	else
		this.tags = [];
	this.changed();
	return this;
}

// Get the tags for a tiddler as a string (space delimited, using [[brackets]] for tags containing spaces)
Tiddler.prototype.getTags = function()
{
	if(this.tags)
		{
		var results = [];
		for(var t=0; t<this.tags.length; t++)
			results.push(String.encodeTiddlyLink(this.tags[t]));
		return results.join(" ");
		}
	else
		return "";
}

var regexpBackSlashEn = new RegExp("\\\\n","mg");
var regexpBackSlash = new RegExp("\\\\","mg");
var regexpBackSlashEss = new RegExp("\\\\s","mg");
var regexpNewLine = new RegExp("\n","mg");
var regexpCarriageReturn = new RegExp("\r","mg");

// Static method to Convert "\n" to newlines, "\s" to "\"
Tiddler.unescapeLineBreaks = function(text)
{
	if(text && text != "")
		return text.replace(regexpBackSlashEn,"\n").replace(regexpBackSlashEss,"\\").replace(regexpCarriageReturn,"");
	else
		return "";
}

// Convert newlines to "\n", "\" to "\s"
Tiddler.prototype.escapeLineBreaks = function()
{
	return this.text.replace(regexpBackSlash,"\\s").replace(regexpNewLine,"\\n").replace(regexpCarriageReturn,"");
}

// Updates the secondary information (like links[] array) after a change to a tiddler
Tiddler.prototype.changed = function()
{
	this.links = [];
	var nextPos = 0;
	var theLink;
	var aliasedPrettyLink = "\\[\\[([^\\[\\]\\|]+)\\|([^\\[\\]\\|]+)\\]\\]";
	var prettyLink = "\\[\\[([^\\]]+)\\]\\]";
	var wikiNameRegExp = new RegExp("(" + config.textPrimitives.wikiLink + ")|(?:" + aliasedPrettyLink + ")|(?:" + prettyLink + ")","mg");
	do {
		var formatMatch = wikiNameRegExp.exec(this.text);
		if(formatMatch)
			{
			if(formatMatch[1] && formatMatch[1].substr(0,1) != config.textPrimitives.unWikiLink && formatMatch[1] != this.title)
				this.links.pushUnique(formatMatch[1]);
			else if(formatMatch[2] && store.tiddlerExists(formatMatch[3]))
				this.links.pushUnique(formatMatch[3]);
			else if(formatMatch[4] && formatMatch[4] != this.title)
				this.links.pushUnique(formatMatch[4]);
			}
	} while(formatMatch);
	return;
}

Tiddler.prototype.getSubtitle = function()
{
	var theModifier = this.modifier;
	if(!theModifier)
		theModifier = config.messages.subtitleUnknown;
	var theModified = this.modified;
	if(theModified)
		theModified = theModified.toLocaleString();
	else
		theModified = config.messages.subtitleUnknown;
	return(theModifier + ", " + theModified);
}

// ---------------------------------------------------------------------------------
// TiddlyWiki() object contains Tiddler()s
// ---------------------------------------------------------------------------------

function TiddlyWiki()
{
	this.tiddlers = {}; // Hashmap by name of tiddlers
	this.namedNotifications = []; // Array of {name:,notify:} of notification functions
	this.dirty = false;
}

// Set the dirty flag
TiddlyWiki.prototype.setDirty = function(dirty)
{
	this.dirty = dirty;
}

// Invoke the notification handlers for a particular tiddler
TiddlyWiki.prototype.notify = function(title,doBlanket)
{
	for(var t=0; t<this.namedNotifications.length; t++)
		{
		var n = this.namedNotifications[t];
		if((n.name == null && doBlanket) || n.name == title)
			n.notify(title);
		}
}

// Invoke the notification handlers for all tiddlers
TiddlyWiki.prototype.notifyAll = function()
{
	for(var t=0; t<this.namedNotifications.length; t++)
		{
		var n = this.namedNotifications[t];
		n.notify(n.name);
		}
}

// Add a notification handler to a tiddler
TiddlyWiki.prototype.addNotification = function(title,fn)
{
	this.namedNotifications.push({name: title, notify: fn});
	return this;
}

// Clear a TiddlyWiki so that it contains no tiddlers
TiddlyWiki.prototype.clear = function(src)
{
	this.tiddlers = {};
	this.dirty = false;
}

TiddlyWiki.prototype.removeTiddler = function(title)
{
	var tiddler = this.tiddlers[title];
	if(tiddler)
		{
		delete this.tiddlers[title];
		this.notify(title,true);
		this.dirty = true;
		}
}

TiddlyWiki.prototype.tiddlerExists = function(title)
{
	var t = this.tiddlers[title];
	var s = config.shadowTiddlers[title];
	return (t != undefined && t instanceof Tiddler) || (s != undefined && s instanceof String);
}

TiddlyWiki.prototype.getTiddlerText = function(title,defaultText)
{
	if(!title)
		return(defaultText);
	var tiddler = this.tiddlers[title];
	if(tiddler)
		return tiddler.text;
	else if(config.shadowTiddlers[title])
		return config.shadowTiddlers[title];
	else if(defaultText)
		return defaultText;
	else
		return null;
}

TiddlyWiki.prototype.getRecursiveTiddlerText = function(title,defaultText,depth)
{
	var bracketRegExp = new RegExp("(?:\\[\\[([^\\]]+)\\]\\])","mg");
	var text = this.getTiddlerText(title,defaultText);
	if(text == null)
		return "";
	var textOut = [];
	var lastPos = 0;
	do {
		var match = bracketRegExp.exec(text);
		if(match)
			{
			textOut.push(text.substr(lastPos,match.index-lastPos));
			if(match[1])
				{
				if(depth <= 0)
					textOut.push(match[1]);
				else
					textOut.push(this.getRecursiveTiddlerText(match[1],match[1],depth-1));
				}
			lastPos = match.index + match[0].length;
			}
		else
			textOut.push(text.substr(lastPos));
	} while(match);
	return(textOut.join(""));
}

TiddlyWiki.prototype.saveTiddler = function(title,newTitle,newBody,modifier,modified,tags)
{
	var tiddler = this.tiddlers[title];
	if(tiddler)
		delete this.tiddlers[title];
	else
		tiddler = new Tiddler();
	tiddler.set(newTitle,newBody,modifier,modified,tags);
	this.tiddlers[newTitle] = tiddler;
	if(title != newTitle)
		this.notify(title,true);
	this.notify(newTitle,true);
	this.dirty = true;
	return tiddler;
}

TiddlyWiki.prototype.createTiddler = function(title)
{
	tiddler = this.tiddlers[title];
	if(!tiddler)
		{
		tiddler = new Tiddler();
		this.tiddlers[title] = tiddler;
		this.dirty = true;
		}
	return tiddler;
}

// Load contents of a tiddlywiki from an HTML DIV
TiddlyWiki.prototype.loadFromDiv = function(srcID,idPrefix)
{
	if(document.normalize)
		document.normalize();
	var lenPrefix = idPrefix.length;
	var store = document.getElementById(srcID).childNodes;
	for(var t = 0; t < store.length; t++)
		{
		var e = store[t];
		var title = null;
		if(e.getAttribute)
			title = e.getAttribute("tiddler");
		if(!title && e.id && e.id.substr(0,lenPrefix) == idPrefix)
			title = e.id.substr(lenPrefix);
		if(title && title != "")
			{
			var tiddler = this.createTiddler(title);
			tiddler.loadFromDiv(e,title);
			}
		}
	this.dirty = false;
}

// Return an array of tiddlers matching a search string
TiddlyWiki.prototype.search = function(searchText,caseSensitive,useRegExp,sortField,excludeTag)
{
	if (!useRegExp)
		searchText = searchText.escapeRegExp();
	var regExp = new RegExp(searchText,caseSensitive ? "m" : "im");
	var candidates = this.reverseLookup("tags",excludeTag,false);
	var results = [];
	for(var t=0; t<candidates.length; t++)
		{
		if(regExp.test(candidates[t].title) || regExp.test(candidates[t].text))
			results.push(candidates[t]);
		}
	if(!sortField)
		sortField = "title";
	results.sort(function (a,b) {if(a[sortField] == b[sortField]) return(0); else return (a[sortField] < b[sortField]) ? -1 : +1; });
	return results;
}

// Return an array of all the tags in use. Each member of the array is another array where [0] is the name of the tag and [1] is the number of occurances
TiddlyWiki.prototype.getTags = function()
{
	var results = [];
	for(var t in this.tiddlers)
		{
		var tiddler = this.tiddlers[t];
		for(g=0; g<tiddler.tags.length; g++)
			{
			var tag = tiddler.tags[g];
			var f = false;
			for(var c=0; c<results.length; c++)
				if(results[c][0] == tag)
					{
					f = true;
					results[c][1]++;
					}
			if(!f)
				results.push([tag,1]);
			}
		}
	results.sort(function (a,b) {if(a[0] == b[0]) return(0); else return (a[0] < b[0]) ? -1 : +1; });
	return results;
}

// Return an array of the tiddlers that are tagged with a given tag
TiddlyWiki.prototype.getTaggedTiddlers = function(tag,sortField)
{
	return this.reverseLookup("tags",tag,true,sortField);
}

// Return an array of the tiddlers that link to a given tiddler
TiddlyWiki.prototype.getReferringTiddlers = function(title,unusedParameter,sortField)
{
	return this.reverseLookup("links",title,true,sortField);
}

// Return an array of the tiddlers that do or do not have a specified entry in the specified storage array (ie, "links" or "tags")
// lookupMatch == true to match tiddlers, false to exclude tiddlers
TiddlyWiki.prototype.reverseLookup = function(lookupField,lookupValue,lookupMatch,sortField)
{
	var results = [];
	for(var t in this.tiddlers)
		{
		var tiddler = this.tiddlers[t];
		var f = !lookupMatch;
		for(var lookup=0; lookup<tiddler[lookupField].length; lookup++)
			if(tiddler[lookupField][lookup] == lookupValue)
				f = lookupMatch;
		if(f)
			results.push(tiddler);
		}
	if(!sortField)
		sortField = "title";
	results.sort(function (a,b) {if(a[sortField] == b[sortField]) return(0); else return (a[sortField] < b[sortField]) ? -1 : +1; });
	return results;
}

// Return the tiddlers as a sorted array
TiddlyWiki.prototype.getTiddlers = function(field)
{
	var results = [];
	for(var t in this.tiddlers)
		results.push(this.tiddlers[t]);
	if(field)
		results.sort(function (a,b) {if(a[field] == b[field]) return(0); else return (a[field] < b[field]) ? -1 : +1; });
	return results;
}

// Return array of names of tiddlers that are referred to but not defined
TiddlyWiki.prototype.getMissingLinks = function(sortField)
{
	var results = [];
	for(var t in this.tiddlers)
		{
		var tiddler = this.tiddlers[t];
		for(var n=0; n<tiddler.links.length;n++)
			{
			var link = tiddler.links[n];
			if(this.tiddlers[link] == null)
				results.pushUnique(link);
			}
		}
	results.sort();
	return results;
}

// Return an array of names of tiddlers that are defined but not referred to
TiddlyWiki.prototype.getOrphans = function()
{
	var results = [];
	for(var t in this.tiddlers)
		if(this.getReferringTiddlers(t).length == 0)
			results.push(t);
	results.sort();
	return results;
}

// ---------------------------------------------------------------------------------
// Tiddler functions
// ---------------------------------------------------------------------------------

// Display several tiddlers from a list of space separated titles
function displayTiddlers(src,titles,state,highlightText,highlightCaseSensitive,animate,slowly)
{
	var tiddlerNames = titles.readBracketedList();
	for(var t = tiddlerNames.length-1;t>=0;t--)
		displayTiddler(src,tiddlerNames[t],state,highlightText,highlightCaseSensitive,animate,slowly);
}

// Display a tiddler with animation and scrolling, as though a link to it has been clicked on
//	src = source element object (eg link) for animation effects and positioning
//	title = title of tiddler to display
//	state = 0 is default or current state, 1 is read only and 2 is edittable
//	highlightText = text to highlight in the displayed tiddler
//	highlightCaseSensitive = flag for whether the highlight text is case sensitive
function displayTiddler(src,title,state,highlightText,highlightCaseSensitive,animate,slowly)
{
	var place = document.getElementById("tiddlerDisplay");
	var after = findContainingTiddler(src); // Which tiddler this one will be positioned after
	var before;
	if(after == null)
		before = place.firstChild;
	else if(after.nextSibling)
		before = after.nextSibling;
	else
		before = null;
	var theTiddler = createTiddler(place,before,title,state,highlightText,highlightCaseSensitive);
	if(src)
		{
		if(config.options.chkAnimate && (animate == undefined || animate == true))
			anim.startAnimating(new Zoomer(title,src,theTiddler,slowly),new Scroller(theTiddler,slowly));
		else
			window.scrollTo(0,ensureVisible(theTiddler));
		}
}

// Create a tiddler if it doesn't exist (with no fancy animating)
//	place = parent element
//	before = node before which to create/move the tiddler
//	title = title of tiddler to display
//	state = 0 is default or current state, 1 is read only and 2 is edittable
//	highlightText = text to highlight in the displayed tiddler
//	highlightCaseSensitive = flag for whether the highlight text is case sensitive
function createTiddler(place,before,title,state,highlightText,highlightCaseSensitive)
{
	var theTiddler = createTiddlerSkeleton(place,before,title);
	createTiddlerTitle(title,highlightText,highlightCaseSensitive);
	var theViewer = document.getElementById("viewer" + title);
	var theEditor = document.getElementById("editorWrapper" + title);
	switch(state)
		{
		case 0:
			if(!theViewer && !theEditor)
				{
				createTiddlerToolbar(title,false);
				createTiddlerViewer(title,highlightText,highlightCaseSensitive);
				createTiddlerFooter(title,false);
				}
			break;
		case 1: // Viewer
			if(theViewer)
				theViewer.parentNode.removeChild(theViewer);
			if(theEditor)
				theEditor.parentNode.removeChild(theEditor);
			createTiddlerToolbar(title,false);
			createTiddlerViewer(title,highlightText,highlightCaseSensitive);
			createTiddlerFooter(title,false);
			break;
		case 2: // Editor
			if(!theEditor)
				{
				if(theViewer)
					theViewer.parentNode.removeChild(theViewer);
				createTiddlerToolbar(title,true);
				createTiddlerEditor(title);
				createTiddlerFooter(title,true);
				}
			break;
		}
	return(theTiddler);
}

function refreshTiddler(title)
{
	var theViewer = document.getElementById("viewer" + title);
	if(theViewer)
		{
		theViewer.parentNode.removeChild(theViewer);
		createTiddlerViewer(title,null,null);
		}
}

function createTiddlerSkeleton(place,before,title)
{
	var theTiddler = document.getElementById("tiddler" + title);
	if(!theTiddler)
		{
		theTiddler = createTiddlyElement(null,"div","tiddler" + title,"tiddler",null);
		theTiddler.onmouseover = onMouseOverTiddler;
		theTiddler.onmouseout = onMouseOutTiddler;
		theTiddler.ondblclick = onDblClickTiddler;
		var theInnerTiddler = createTiddlyElement(theTiddler,"div",null,"unselectedTiddler",null);
		var theToolbar = createTiddlyElement(theInnerTiddler,"div","toolbar" + title,"toolbar", null);
		var theTitle = createTiddlyElement(theInnerTiddler,"div","title" + title,"title",null);
		var theBody = createTiddlyElement(theInnerTiddler,"div","body" + title,"body",null);
		var theFooter = createTiddlyElement(theInnerTiddler,"div","footer" + title,"footer",null);
		place.insertBefore(theTiddler,before);
		}
	return(theTiddler);
}

function createTiddlerTitle(title,highlightText,highlightCaseSensitive)
{
	var theTitle = document.getElementById("title" + title);
	if(theTitle)
		{
		removeChildren(theTitle);
		createTiddlyText(theTitle,title);
		if(store.tiddlerExists(title))
			theTitle.title = store.tiddlers[title].getSubtitle();
		}
}

// Create a tiddler toolbar according to whether it's an editor or not
function createTiddlerToolbar(title,isEditor)
{
	var theToolbar = document.getElementById("toolbar" + title);
	var lingo = config.views;
	if(theToolbar)
		{
		removeChildren(theToolbar);
		insertSpacer(theToolbar);
		if(isEditor)
			{
			// Editor toolbar
			lingo = lingo.editor;
			createTiddlyButton(theToolbar,lingo.toolbarDone.text,lingo.toolbarDone.tooltip,onClickToolbarSave);
			insertSpacer(theToolbar);
			createTiddlyButton(theToolbar,lingo.toolbarCancel.text,lingo.toolbarCancel.tooltip,onClickToolbarUndo);
			insertSpacer(theToolbar);
			createTiddlyButton(theToolbar,lingo.toolbarDelete.text,lingo.toolbarDelete.tooltip,onClickToolbarDelete);
			}
		else
			{
			// Viewer toolbar
			lingo = lingo.wikified;
			createTiddlyButton(theToolbar,lingo.toolbarClose.text,lingo.toolbarClose.tooltip,onClickToolbarClose);
			insertSpacer(theToolbar);
			if(!readOnly)
				{
				createTiddlyButton(theToolbar,lingo.toolbarEdit.text,lingo.toolbarEdit.tooltip,onClickToolbarEdit);
				insertSpacer(theToolbar);
				}
			createTiddlyButton(theToolbar,lingo.toolbarPermalink.text,lingo.toolbarPermalink.tooltip,onClickToolbarPermaLink);
			insertSpacer(theToolbar);
			createTiddlyButton(theToolbar,lingo.toolbarReferences.text,lingo.toolbarReferences.tooltip,onClickToolbarReferences);
			}
		insertSpacer(theToolbar);
		}
}

function createTiddlerPopup(srcElement)
{
	var popup = document.getElementById("popup");
	if(popup && popup.nextSibling == srcElement)
		{
		hideTiddlerPopup();
		return null;
		}
	if(popup)
		popup.parentNode.removeChild(popup);
	popup = createTiddlyElement(null,"div","popup",null,null);
	var leftPx = srcElement.offsetLeft;
	var topPx = srcElement.offsetTop;
	var heightPx = srcElement.offsetHeight;
	if (leftPx <= 1 && srcElement.parentNode.offsetLeft > 0)
		leftPx = srcElement.parentNode.offsetLeft;
	if (topPx <= 1 && srcElement.parentNode.offsetTop > 0)
		topPx = srcElement.parentNode.offsetTop;
	if (heightPx <= 1 && srcElement.parentNode.offsetHeight > 0)
		heightPx = srcElement.parentNode.offsetHeight;
	popup.style.left = leftPx + "px";
	popup.style.top = topPx + heightPx + "px";
	popup.style.display = "block";
	srcElement.onmouseout = onMouseOutTiddlerPopup;
	srcElement.appendChild(popup);
	return popup;
}

function scrollToTiddlerPopup(popup,slowly)
{
	if(config.options.chkAnimate)
		anim.startAnimating(new Scroller(popup,slowly));
	else
		window.scrollTo(0,ensureVisible(popup));
}

function onMouseOutTiddlerPopup(e)
{
	if (!e) var e = window.event;
	var related = (e.relatedTarget) ? e.relatedTarget : e.toElement;
	try
		{
		while (related != this && related && related.nodeName && related.nodeName.toLowerCase() != "body")
			related = related.parentNode;
		}
	catch(e)
		{
		related = null;
		}
	if(related != this)
		{
		this.onmouseout = null;
		hideTiddlerPopup();
		}
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}

function hideTiddlerPopup()
{
	var popup = document.getElementById("popup");
	if(popup)
		popup.parentNode.removeChild(popup);
}

// Create the body section of a read-only tiddler
function createTiddlerViewer(title,highlightText,highlightCaseSensitive)
{
	var theBody = document.getElementById("body" + title);
	if(theBody)
		{
		var tiddlerText = store.getTiddlerText(title);
		var theViewer = createTiddlyElement(theBody,"div","viewer" + title,"viewer",null);
		if(store.tiddlerExists(title))
			theViewer.setAttribute("tags",tiddler.tags.join(" "));
		if(!tiddlerText)
			{
			tiddlerText = config.views.wikified.defaultText.format([title]);
			theViewer.style.fontStyle = "italic";
			}
		wikify(tiddlerText,theViewer,highlightText,highlightCaseSensitive);
		theViewer.style.overflow = "visible";
		theViewer.style.height = "auto";
		}
}

// Create the footer section of a tiddler
function createTiddlerFooter(title,isEditor)
{
	var theFooter = document.getElementById("footer" + title);
	var tiddler = store.tiddlers[title];
	if(theFooter && tiddler instanceof Tiddler)
		{
		removeChildren(theFooter);
		insertSpacer(theFooter);
		if(isEditor)
			{
			}
		else
			{
			var lingo = config.views.wikified.tag;
			var prompt = tiddler.tags.length == 0 ? lingo.labelNoTags : lingo.labelTags;
			var theTags = createTiddlyElement(theFooter,"div",null,null,prompt);
			for(var t=0; t<tiddler.tags.length; t++)
				{
				var theTag = createTagButton(theTags,tiddler.tags[t],tiddler.title);
				insertSpacer(theTags);
				}
			}
		}
}

// Create a button for a tag with a popup listing all the tiddlers that it tags
function createTagButton(place,tag,excludeTiddler)
{
	var theTag = createTiddlyButton(place,tag,config.views.wikified.tag.tooltip.format([tag]),onClickTag);
	theTag.setAttribute("tag",tag);
	if(excludeTiddler)
		theTag.setAttribute("tiddler",excludeTiddler);
	return(theTag);
}

// Create the body section of an edittable tiddler
function createTiddlerEditor(title)
{
	var theBody = document.getElementById("body" + title);
	if(theBody)
		{
		var tiddlerText = store.getTiddlerText(title);
		var tiddlerExists = (tiddlerText != null);
		if(!tiddlerExists)
			tiddlerText = config.views.editor.defaultText.format([title]);
		var theEditor = createTiddlyElement(theBody,"div","editorWrapper" + title,"editor",null);
		theEditor.onkeypress = onEditKey;
		var theTitleBox = createTiddlyElement(theEditor,"input","editorTitle" + title,null,null);
		theTitleBox.setAttribute("type","text");
		theTitleBox.value = title;
		theTitleBox.setAttribute("size","40");
		theTitleBox.setAttribute("autocomplete","off");
		var theBodyBox = createTiddlyElement(theEditor,"textarea","editorBody" + title,null,null);
		theBodyBox.value = tiddlerText;
		var rows = 10;
		var lines = tiddlerText.match(regexpNewLine);
		if(lines != null && lines.length > rows)
			rows = lines.length + 5;
		theBodyBox.setAttribute("rows",rows);
		var theTagsBox = createTiddlyElement(theEditor,"input","editorTags" + title,null,null);
		theTagsBox.setAttribute("type","text");
		var tiddler = store.tiddlers[title];
		theTagsBox.value = tiddler instanceof Tiddler ? tiddler.getTags() : "";
		theTagsBox.setAttribute("size","40");
		theTagsBox.setAttribute("autocomplete","off");
		var tagPrompt = createTiddlyElement(theEditor,"div",null,"editorFooter",config.views.editor.tagPrompt);
		insertSpacer(tagPrompt);
		var lingo = config.views.editor.tagChooser;
		var addTag = createTiddlyButton(tagPrompt,lingo.text,lingo.tooltip,onClickAddTag);
		addTag.setAttribute("tiddler",title);
		theBodyBox.focus();
		}
}

function saveTiddler(title,minorUpdate)
{
	var titleBox = document.getElementById("editorTitle" + title);
	var newTitle = titleBox.value;
	if(store.tiddlerExists(newTitle))
		{
		if(newTitle != title && !confirm(config.messages.overwriteWarning.format([newTitle.toString()])))
			{
			titleBox.focus();
			titleBox.select();
			return;
			}
		}
	var body = document.getElementById("editorBody" + title);
	var newBody = body.value;
	newBody = newBody.replace(/\r/mg,"");
	var newTags = document.getElementById("editorTags" + title).value;
	blurTiddler(title);
	if(config.options.chkForceMinorUpdate)
		minorUpdate = !minorUpdate;
	var newDate = new Date();
	store.saveTiddler(title,newTitle,newBody,config.options.txtUserName,minorUpdate ? undefined : new Date(),newTags);
	displayTiddler(null,newTitle,1,null,null,null,false,false);
	// Close the old tiddler if this is a rename
	if(title != newTitle)
		{
		var oldTiddler = document.getElementById("tiddler" + title);
		var newTiddler = document.getElementById("tiddler" + newTitle);
		oldTiddler.parentNode.replaceChild(newTiddler,oldTiddler);
		}
	if(config.options.chkAutoSave)
		saveChanges();
}

function selectTiddler(title)
{
	var e = document.getElementById("tiddler" + title);
	if(e != null)
		e.firstChild.className = "selectedTiddler";
}

function deselectTiddler(title)
{
	var e = document.getElementById("tiddler" + title);
	if(e != null)
		e.firstChild.className = "unselectedTiddler";
}

function blurTiddler(title)
{
	var body = document.getElementById("editorBody" + title);
	if(body)
		{
		body.focus();
		body.blur();
		}
}

function deleteTiddler(title)
{
	closeTiddler(title,false);
	store.removeTiddler(title);
	// Autosave
	if(config.options.chkAutoSave)
		saveChanges();
}

function closeTiddler(title,slowly)
{
	var tiddler = document.getElementById("tiddler" + title);
	if(tiddler != null)
		{
		scrubIds(tiddler);
		if(config.options.chkAnimate)
			anim.startAnimating(new Slider(tiddler,false,slowly,"all"));
		else
			tiddler.parentNode.removeChild(tiddler);
		}
}

function scrubIds(e)
{
	if(e.id)
		e.id = null;
	var children = e.childNodes;
	for(var t=0; t<children.length; t++)
		{
		var c = children[t];
		if(c.id)
			c.id = null;
		}
}

function closeAllTiddlers()
{
	clearMessage();
	var place = document.getElementById("tiddlerDisplay");
	var tiddler = place.firstChild;
	var nextTiddler;
	while(tiddler)
		{
		nextTiddler = tiddler.nextSibling;
		if(tiddler.id)
			if(tiddler.id.substr(0,7) == "tiddler")
				{
				var title = tiddler.id.substr(7);
				if(!document.getElementById("editorWrapper" + title))
					place.removeChild(tiddler);
				}
		tiddler = nextTiddler;
		}
}

// ---------------------------------------------------------------------------------
// Message area
// ---------------------------------------------------------------------------------

function displayMessage(text,linkText)
{
	var msgArea = document.getElementById("messageArea");
	var msg;
	if(linkText)
		{
		msg = createTiddlyElement(msgArea,"div",null,null,null);
		var link = createTiddlyElement(msg,"a",null,null,text);
		link.href = linkText;
		link.target = "_blank";
		}
	else
		msg = createTiddlyElement(msgArea,"div",null,null,text);
	msgArea.style.display = "block";
}

function clearMessage()
{
	var msgArea = document.getElementById("messageArea");
	removeChildren(msgArea);
	msgArea.style.display = "none";
}

// ---------------------------------------------------------------------------------
// Menu and sidebar functions
// ---------------------------------------------------------------------------------

function refreshStory(hint)
{
	var hits = hint ? store.getReferringTiddlers(hint) : null;
	var displayNodes = document.getElementById("tiddlerDisplay").childNodes;
	for(var t=0;t<displayNodes.length;t++)
		{
		var theId = displayNodes[t].id;
		if(theId && theId.substr(0,7) == "tiddler")
			{
			var title = theId.substr(7);
			if(hint)
				{
				var f = false;
				for(var h=0; h<hits.length; h++)
					if(hits[h].title == title)
						f = true
				if(f)
					refreshTiddler(title);
				}
			else
				refreshTiddler(title);
			}
		}
}

function refreshTabs(hint)
{
	refreshSpecialItem("sidebarTabs","SideBarTabs","SideBarTabs");
}

function refreshMenu(hint)
{
	refreshSpecialItem("mainMenu","MainMenu","MainMenu");
}

function refreshTitle(title)
{
	refreshSpecialItem("siteTitle",title,"SiteTitle");
	refreshPageTitle();
}

function refreshSubtitle(title)
{
	refreshSpecialItem("siteSubtitle",title,"SiteSubtitle");
	refreshPageTitle();
}

function refreshPageTitle()
{
	document.title = getElementText("siteTitle") + " - " + getElementText("siteSubtitle");
}

function refreshSidebar(title)
{
	refreshSpecialItem("sidebarOptions",title,"SideBarOptions");
}

function refreshSpecialItem(elementID,title,defaultText)
{
	var place = document.getElementById(elementID);
	removeChildren(place);
	wikify(store.getTiddlerText(title,defaultText),place,null,null);
}

function refreshStyles(title)
{
	setStylesheet(title == null ? "" : store.getRecursiveTiddlerText(title,"",10));
}

// ---------------------------------------------------------------------------------
// Options cookie stuff
// ---------------------------------------------------------------------------------

function loadOptionsCookie()
{
	var cookies = document.cookie.split(";");
	for(var c=0; c<cookies.length; c++)
		{
		var p = cookies[c].indexOf("=");
		if(p != -1)
			{
			var name = cookies[c].substr(0,p).trim();
			var value = cookies[c].substr(p+1).trim();
			switch(name.substr(0,3))
				{
				case "txt":
					config.options[name] = unescape(value);
					break;
				case "chk":
					config.options[name] = value == "true";
					break;
				}
			}
		}
}

function saveOptionCookie(name)
{
	var c = name + "=";
	switch(name.substr(0,3))
		{
		case "txt":
			c += escape(config.options[name].toString());
			break;
		case "chk":
			c += config.options[name] ? "true" : "false";
			break;
		}
	c += "; expires=Fri, 1 Jan 2038 12:00:00 UTC; path=/";
	document.cookie = c;
}

// ---------------------------------------------------------------------------------
// Saving
// ---------------------------------------------------------------------------------

var saveUsingSafari = false;
var startSaveArea = '<div id="' + 'storeArea">'; // Split up into two so that indexOf() of this source doesn't find it
var endSaveArea = '</d' + 'iv>';

// Check if there any unsaved changes before exitting
function checkUnsavedChanges()
{
	if(store.dirty)
		{
		if(confirm(config.messages.unsavedChangesWarning))
			saveChanges();
		}
}

// Save this tiddlywiki with the pending changes
function saveChanges()
{
	clearMessage();
	// Get the URL of the document
	var originalPath = document.location.toString();
	// Check we were loaded from a file URL
	if(originalPath.substr(0,5) != "file:")
		{
		alert(config.messages.notFileUrlError);
		displayTiddler(null,"SaveChanges",0,null,null,false,false);
		return;
		}
	// Remove any location part of the URL
	var hashPos = originalPath.indexOf("#");
	if(hashPos != -1)
		originalPath = originalPath.substr(0,hashPos);
	// Convert to a native file format assuming
	// "file:///x:/path/path/path..." - pc local file --> "x:\path\path\path..."
	// "file://///server/share/path/path/path..." - FireFox pc network file --> "\\server\share\path\path\path..."
	// "file:///path/path/path..." - mac/unix local file --> "/path/path/path..."
	// "file://server/share/path/path/path..." - pc network file --> "\\server\share\path\path\path..."
	var localPath;
	if(originalPath.charAt(9) == ":") // pc local file
		localPath = unescape(originalPath.substr(8)).replace(new RegExp("/","g"),"\\");
	else if(originalPath.indexOf("file://///") == 0) // FireFox pc network file
		localPath = "\\\\" + unescape(originalPath.substr(10)).replace(new RegExp("/","g"),"\\");
	else if(originalPath.indexOf("file:///") == 0) // mac/unix local file
		localPath = unescape(originalPath.substr(7));
	else if(originalPath.indexOf("file:/") == 0) // mac/unix local file
		localPath = unescape(originalPath.substr(5));
	else // pc network file
		localPath = "\\\\" + unescape(originalPath.substr(7)).replace(new RegExp("/","g"),"\\");
	// Load the original file
	var original = loadFile(localPath);
	if(original == null)
		{
		alert(config.messages.cantSaveError);
		displayTiddler(null,"SaveChanges",0,null,null,false,false);
		return;
		}
	// Locate the storeArea div's
	var posOpeningDiv = original.indexOf(startSaveArea);
	var posClosingDiv = original.lastIndexOf(endSaveArea);
	if((posOpeningDiv == -1) || (posClosingDiv == -1))
		{
		alert(config.messages.invalidFileError.format([localPath]));
		return;
		}
	// Save the backup
	if(config.options.chkSaveBackups)
		{
		var backupPath = localPath.substr(0,localPath.lastIndexOf(".")) + "." + (new Date()).convertToYYYYMMDDHHMMSSMMM() + ".html";
		var backup = saveFile(backupPath,original);
		if(backup)
			displayMessage(config.messages.backupSaved,"file://" + backupPath);
		else
			alert(config.messages.backupFailed);
		}
	// Save Rss
	if(config.options.chkGenerateAnRssFeed)
		{
		var rssPath = localPath.substr(0,localPath.lastIndexOf(".")) + ".xml";
		var rssSave = saveFile(rssPath,convertUnicodeToUTF8(generateRss()));
		if(rssSave)
			displayMessage(config.messages.rssSaved,"file://" + rssPath);
		else
			alert(config.messages.rssFailed);
		}
	// Save empty template
	if(config.options.chkSaveEmptyTemplate)
		{
		var emptyPath,p;
		if((p = localPath.lastIndexOf("/")) != -1)
			emptyPath = localPath.substr(0,p) + "/empty.html";
		else if((p = localPath.lastIndexOf("\\")) != -1)
			emptyPath = localPath.substr(0,p) + "\\empty.html";
		else
			emptyPath = localPath + ".empty.html";
		var empty = original.substr(0,posOpeningDiv + startSaveArea.length) + convertUnicodeToUTF8(generateEmpty()) + original.substr(posClosingDiv);
		var emptySave = saveFile(emptyPath,empty);
		if(emptySave)
			displayMessage(config.messages.emptySaved,"file://" + emptyPath);
		else
			alert(config.messages.emptyFailed);
		}
	// Save new file
	var revised = original.substr(0,posOpeningDiv + startSaveArea.length) + 
				convertUnicodeToUTF8(allTiddlersAsHtml()) + "\n\t\t" +
				original.substr(posClosingDiv);
	var newSiteTitle = convertUnicodeToUTF8((getElementText("siteTitle") + " - " + getElementText("siteSubtitle")).htmlEncode());
	revised = revised.replace(new RegExp("<title>[^<]*</title>", "im"),"<title>"+ newSiteTitle +"</title>");
	var save = saveFile(localPath,revised);
	if(save)
		{
		displayMessage(config.messages.mainSaved,"file://" + localPath);
		store.setDirty(false);
		}
	else
		alert(config.messages.mainFailed);
}

function generateRss()
{
	var s = [];
	var d = new Date();
	var u = store.getTiddlerText("SiteUrl",null);
	// Assemble the header
	s.push("<" + "?xml version=\"1.0\"?" + ">");
	s.push("<rss version=\"2.0\">");
	s.push("<channel>");
	s.push("<title>" + store.getTiddlerText("SiteTitle","").htmlEncode() + "</title>");
	if(u)
		s.push("<link>" + u.htmlEncode() + "</link>");
	s.push("<description>" + store.getTiddlerText("SiteSubtitle","").htmlEncode() + "</description>");
	s.push("<language>en-us</language>");
	s.push("<copyright>Copyright " + d.getFullYear() + " " + config.options.txtUserName.htmlEncode() + "</copyright>");
	s.push("<pubDate>" + d.toGMTString() + "</pubDate>");
	s.push("<lastBuildDate>" + d.toGMTString() + "</lastBuildDate>");
	s.push("<docs>http://blogs.law.harvard.edu/tech/rss</docs>");
	s.push("<generator>TiddlyWiki " + version.major + "." + version.minor + "." + version.revision + "</generator>");
	// The body
	var tiddlers = store.getTiddlers("modified");
	var n = config.numRssItems > tiddlers.length ? 0 : tiddlers.length-config.numRssItems;
	for (var t=tiddlers.length-1; t>=n; t--)
		s.push(tiddlers[t].saveToRss(u));
	// And footer
	s.push("</channel>");
	s.push("</rss>");
	// Save it all
	return s.join("\n");
}

function generateEmpty()
{
	var systemTiddlers = store.getTaggedTiddlers("systemTiddlers");
	var savedTiddlers = [];
	for(var s=0;s<systemTiddlers.length;s++)
		savedTiddlers.push(systemTiddlers[s].saveToDiv());
	return savedTiddlers.join("\n");
}

function allTiddlersAsHtml()
{
	var savedTiddlers = [];
	var tiddlers = store.getTiddlers("title");
	for (var t = 0; t < tiddlers.length; t++)
		savedTiddlers.push(tiddlers[t].saveToDiv());
	return savedTiddlers.join("\n");
}

// UTF-8 encoding rules:
// 0x0000 - 0x007F:	0xxxxxxx
// 0x0080 - 0x07FF:	110xxxxx 10xxxxxx
// 0x0800 - 0xFFFF:	1110xxxx 10xxxxxx 10xxxxxx

function convertUTF8ToUnicode(u)
{
	var s = "";
	var t = 0;
	var b1, b2, b3;
	while(t < u.length)
		{
		b1 = u.charCodeAt(t++);
		if(b1 < 0x80)
			s += String.fromCharCode(b1);
		else if(b1 < 0xE0)
			{
			b2 = u.charCodeAt(t++);
			s += String.fromCharCode(((b1 & 0x1F) << 6) | (b2 & 0x3F));
			}
		else
			{
			b2 = u.charCodeAt(t++);
			b3 = u.charCodeAt(t++);
			s += String.fromCharCode(((b1 & 0xF) << 12) | ((b2 & 0x3F) << 6) | (b3 & 0x3F));
			}
	}
	return(s);
}

function convertUnicodeToUTF8(s)
{
	if(saveUsingSafari)
		return s;
	else if(window.Components)
		return mozConvertUnicodeToUTF8(s);
	else
		return manualConvertUnicodeToUTF8(s);
}

function manualConvertUnicodeToUTF8(s)
{
	var u = [];
	for(var t=0;t<s.length;t++)
		{
		var c = s.charCodeAt(t);
		if(c <= 0x7F)
			u.push(String.fromCharCode(c));
		else
			u.push("&#" + c.toString() + ";");
		}
	return(u.join(""));
}

function mozConvertUnicodeToUTF8(s)
{
	netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
	var converter = Components.classes["@mozilla.org/intl/scriptableunicodeconverter"].createInstance(Components.interfaces.nsIScriptableUnicodeConverter);
	converter.charset = "UTF-8";
	var u = converter.ConvertFromUnicode(s);
	var fin = converter.Finish();
	if(fin.length > 0)
		return u + fin;
	else
		return u;
}

function saveFile(fileUrl, content)
{
	var r = null;
	if(saveUsingSafari)
		r = safariSaveFile(fileUrl, content);
	if((r == null) || (r == false))
		r = mozillaSaveFile(fileUrl, content);
	if((r == null) || (r == false))
		r = ieSaveFile(fileUrl, content);
	if((r == null) || (r == false))
		r = operaSaveFile(fileUrl, content);
	return(r);
}

function loadFile(fileUrl)
{
	var r = null;
	if(saveUsingSafari)
		r = safariLoadFile(fileUrl);
	if((r == null) || (r == false))
		r = mozillaLoadFile(fileUrl);
	if((r == null) || (r == false))
		r = ieLoadFile(fileUrl);
	if((r == null) || (r == false))
		r = operaLoadFile(fileUrl);
	return(r);
}

// Returns null if it can't do it, false if there's an error, true if it saved OK
function ieSaveFile(filePath, content)
{
	try
		{
		var fso = new ActiveXObject("Scripting.FileSystemObject");
		}
	catch(e)
		{
		//alert("Exception while attempting to save\n\n" + e.toString());
		return(null);
		}
	var file = fso.OpenTextFile(filePath,2,-1,0);
	file.Write(content);
	file.Close();
	return(true);
}

// Returns null if it can't do it, false if there's an error, or a string of the content if successful
function ieLoadFile(filePath)
{
	try
		{
		var fso = new ActiveXObject("Scripting.FileSystemObject");
		}
	catch(e)
		{
		//alert("Exception while attempting to load\n\n" + e.toString());
		return(null);
		}
	var file = fso.OpenTextFile(filePath,1);
	var content = file.ReadAll();
	file.Close();
	return(content);
}

// Returns null if it can't do it, false if there's an error, true if it saved OK
function mozillaSaveFile(filePath, content)
{
	if(window.Components)
		try
			{
			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
			var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
			file.initWithPath(filePath);
			if (!file.exists())
				file.create(0, 0664);
			var out = Components.classes["@mozilla.org/network/file-output-stream;1"].createInstance(Components.interfaces.nsIFileOutputStream);
			out.init(file, 0x20 | 0x02, 00004,null);
			out.write(content, content.length);
			out.flush();
			out.close();
			return(true);
			}
		catch(e)
			{
			//alert("Exception while attempting to save\n\n" + e);
			return(false);
			}
	return(null);
}

// Returns null if it can't do it, false if there's an error, or a string of the content if successful
function mozillaLoadFile(filePath)
{
	if(window.Components)
		try
			{
			netscape.security.PrivilegeManager.enablePrivilege("UniversalXPConnect");
			var file = Components.classes["@mozilla.org/file/local;1"].createInstance(Components.interfaces.nsILocalFile);
			file.initWithPath(filePath);
			if (!file.exists())
				return(null);
			var inputStream = Components.classes["@mozilla.org/network/file-input-stream;1"].createInstance(Components.interfaces.nsIFileInputStream);
			inputStream.init(file, 0x01, 00004, null);
			var sInputStream = Components.classes["@mozilla.org/scriptableinputstream;1"].createInstance(Components.interfaces.nsIScriptableInputStream);
			sInputStream.init(inputStream);
			return(sInputStream.read(sInputStream.available()));
			}
		catch(e)
			{
			//alert("Exception while attempting to load\n\n" + e);
			return(false);
			}
	return(null);
}

function operaSaveFile(filePath, content)
{
	try
		{
		var s = new java.io.PrintStream(new java.io.FileOutputStream(filePath));
		s.print(content);
		s.close();
		}
	catch(e)
		{
		opera.postError(e);
		return null;
		}
	return true;
}

function operaLoadFile(filePath)
{
	var content = [];
	try
		{
		var r = new java.io.BufferedReader(new java.io.FileReader(filePath));
		var line;
		while ((line = r.readLine()) != null)
			content.push(line);
		r.close();
		}
	catch(e)
		{
		opera.postError(e);
		return null;
		}
	return content.join("\n");
}

function safariFilenameToUrl(filename) {
	return ("file://" + filename);
}

function safariLoadFile(url)
{
	url = safariFilenameToUrl(url);
	var plugin = document.embeds["tiddlyWikiSafariSaver"];
	return plugin.readURL(url);
}

function safariSaveFile(url,content)
{
	url = safariFilenameToUrl(url);
	var plugin = document.embeds["tiddlyWikiSafariSaver"];
	return plugin.writeStringToURL(content,url);
}

// Lifted from http://developer.apple.com/internet/webcontent/detectplugins.html
function detectPlugin()
{
	var daPlugins = detectPlugin.arguments;
	var pluginFound = false;
	if (navigator.plugins && navigator.plugins.length > 0)
		{
		var pluginsArrayLength = navigator.plugins.length;
		for (pluginsArrayCounter=0; pluginsArrayCounter < pluginsArrayLength; pluginsArrayCounter++ )
			{
			var numFound = 0;
			for(namesCounter=0; namesCounter < daPlugins.length; namesCounter++)
				{
				if( (navigator.plugins[pluginsArrayCounter].name.indexOf(daPlugins[namesCounter]) >= 0) || 
						(navigator.plugins[pluginsArrayCounter].description.indexOf(daPlugins[namesCounter]) >= 0) )
					numFound++;
				}
			if(numFound == daPlugins.length)
				{
				pluginFound = true;
				break;
				}
			}
	}
	return pluginFound;
}

// ---------------------------------------------------------------------------------
// Event handlers
// ---------------------------------------------------------------------------------

function onEditKey(e)
{
	if (!e) var e = window.event;
	clearMessage();
	var consume = false;
	switch(e.keyCode)
		{
		case 13: // Ctrl-Enter
		case 10: // Ctrl-Enter on IE PC
		case 77: // Ctrl-Enter is "M" on some platforms
			if(e.ctrlKey && this.id && this.id.substr(0,13) == "editorWrapper")
				{
				blurTiddler(this.id.substr(13));
				saveTiddler(this.id.substr(13),e.shiftKey);
				consume = true;
				}
			break;
		case 27: // Escape
			if(this.id && this.id.substr(0,13) == "editorWrapper")
				{
				blurTiddler(this.id.substr(13));
				displayTiddler(null,this.id.substr(13),1,null,null,false,false);
				consume = true;
				}
			break;
		}
	e.cancelBubble = consume;
	if(consume)
		if (e.stopPropagation) e.stopPropagation();
	return(!consume);

}

// Event handler for clicking on a tiddly link
function onClickTiddlerLink(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	var theLink = theTarget;
	var title = null;
	do {
		title = theLink.getAttribute("tiddlyLink");
		theLink = theLink.parentNode;
	} while(title == null && theLink != null);
	if(title)
		{
		var toggling = e.metaKey || e.ctrlKey;
		if(config.options.chkToggleLinks)
			toggling = !toggling;
		var opening;
		if(toggling && document.getElementById("tiddler" + title))
			closeTiddler(title,e.shiftKey || e.altKey);
		else
			displayTiddler(theTarget,title,0,null,null,true,e.shiftKey || e.altKey);
		}
	clearMessage();
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}

// Event handler for mouse over a tiddler
function onMouseOverTiddler(e)
{
	var tiddler;
	if(this.id.substr(0,7) == "tiddler")
		tiddler = this.id.substr(7);
	if(tiddler)
		selectTiddler(tiddler);
}

// Event handler for mouse out of a tiddler
function onMouseOutTiddler(e)
{
	var tiddler;
	if(this.id.substr(0,7) == "tiddler")
		tiddler = this.id.substr(7);
	if(tiddler)
		deselectTiddler(tiddler);
}

// Event handler for double click on a tiddler
function onDblClickTiddler(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	if(!readOnly && theTarget && theTarget.nodeName.toLowerCase() != "input" && theTarget.nodeName.toLowerCase() != "textarea")
		{
		clearMessage();
		if(document.selection && document.selection.empty)
			document.selection.empty();
		var tiddler;
		if(this.id.substr(0,7) == "tiddler")
			tiddler = this.id.substr(7);
		if(tiddler)
			displayTiddler(null,tiddler,2,null,null,false,false);
		return true;
		}
	else
		return false;
}

// Event handler for clicking on toolbar close
function onClickToolbarClose(e)
{
	if (!e) var e = window.event;
	clearMessage();
	if(this.parentNode.id)
		closeTiddler(this.parentNode.id.substr(7),e.shiftKey || e.altKey);
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}

// Event handler for clicking on toolbar permalink
function onClickToolbarPermaLink(e)
{
	if(this.parentNode.id)
		{
		var title = this.parentNode.id.substr(7);
		var t = encodeURIComponent(String.encodeTiddlyLink(title));
		if(window.location.hash != t)
			window.location.hash = t;
		}
	return false;
}

// Event handler for clicking on toolbar close
function onClickToolbarDelete(e)
{
	clearMessage();
	if(this.parentNode.id)
		deleteTiddler(this.parentNode.id.substr(7));
	return false;
}

// Event handler for clicking on the toolbar references button
function onClickToolbarReferences(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	var popup = createTiddlerPopup(this);
	if(popup && this.parentNode.id)
		{
		var title = this.parentNode.id.substr(7);
		var references = store.getReferringTiddlers(title);
		var c = false;
		for(var r=0; r<references.length; r++)
			if(references[r].title != title)
				{
				createTiddlyLink(popup,references[r].title,true);
				c = true;
				}
		if(!c)
			popup.appendChild(document.createTextNode(config.views.wikified.toolbarReferences.popupNone));
		}
	scrollToTiddlerPopup(popup,false);
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}

// Event handler for clicking on a tiddler tag
function onClickTag(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	var popup = createTiddlerPopup(this);
	var tag = this.getAttribute("tag");
	var title = this.getAttribute("tiddler");
	if(popup && tag)
		{
		var tagged = store.getTaggedTiddlers(tag);
		var c = false;
		for(var r=0;r<tagged.length;r++)
			if(tagged[r].title != title)
				{
				createTiddlyLink(popup,tagged[r].title,true);
				c = true;
				}
		var lingo = config.views.wikified.tag;
		if(c)
			{
			popup.insertBefore(document.createElement("hr"),popup.firstChild);
			var openAll = createTiddlyButton(null,lingo.openAllText.format([tag]),lingo.openAllTooltip,onClickTagOpenAll);
			openAll.setAttribute("tag",tag);
			popup.insertBefore(openAll,popup.firstChild);
			}
		else
			popup.appendChild(document.createTextNode(lingo.popupNone.format([tag])));
		}
	scrollToTiddlerPopup(popup,false);
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}

// Event handler for 'open all' on a tiddler popup
function onClickTagOpenAll(e)
{
	if (!e) var e = window.event;
	var tag = this.getAttribute("tag");
	var tagged = store.getTaggedTiddlers(tag);
	for(var t=tagged.length-1; t>=0; t--)
		displayTiddler(this,tagged[t].title,0,null,null,false,e.shiftKey || e.altKey);
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}

// Event handler for clicking on the 'add tag' button
function onClickAddTag(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	var popup = createTiddlerPopup(this);
	var tiddler = this.getAttribute("tiddler");
	var tags = store.getTags();
	var lingo = config.views.editor.tagChooser;
	if(tags.length == 0)
		createTiddlyElement(popup,"div",null,null,lingo.popupNone);
	for (t=0; t<tags.length; t++)
		{
		var theTag = createTiddlyButton(popup,tags[t][0],lingo.tagTooltip.format([tags[t][0]]),onClickAddTagPopup);
		theTag.setAttribute("tag",tags[t][0]);
		theTag.setAttribute("tiddler",tiddler);
		}
	scrollToTiddlerPopup(popup,false);
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}

// Event handler for clicking on a tag in the 'add tag' popup
function onClickAddTagPopup(e)
{
	if (!e) var e = window.event;
	var theTarget = resolveTarget(e);
	var tiddler = this.getAttribute("tiddler");
	var tag = this.getAttribute("tag");
	var tagsBox = document.getElementById("editorTags" + tiddler);
	if(tagsBox)
		tagsBox.value += " " + String.encodeTiddlyLink(tag);
	e.cancelBubble = true;
	if (e.stopPropagation) e.stopPropagation();
	return(false);
}

// Event handler for clicking on toolbar close
function onClickToolbarEdit(e)
{
	clearMessage();
	if(this.parentNode.id)
		displayTiddler(null,this.parentNode.id.substr(7),2,null,null,false,false);
	return false;
}

// Event handler for clicking on toolbar save
function onClickToolbarSave(e)
{
	if (!e) var e = window.event;
	if(this.parentNode.id)
		saveTiddler(this.parentNode.id.substr(7),e.shiftKey);
	return false;
}

// Event handler for clicking on toolbar save
function onClickToolbarUndo(e)
{
	if(this.parentNode.id)
		displayTiddler(null,this.parentNode.id.substr(7),1,null,null,false,false);
	return false;
}

// Eek... it's bad that this is done via a function rather than a normal, copy-able href
function onClickPermaView()
{
	var tiddlerDisplay = document.getElementById("tiddlerDisplay");
	var links = [];
	for(var t=0;t<tiddlerDisplay.childNodes.length;t++)
		{
		var tiddlerName = tiddlerDisplay.childNodes[t].id.substr(7);
		links.push(String.encodeTiddlyLink(tiddlerName));
		}
	window.location.hash = encodeURIComponent(links.join(" "));
	return false;
}

// ---------------------------------------------------------------------------------
// Animation engine
// ---------------------------------------------------------------------------------

function Animator()
{
	this.running = 0; // Incremented at start of each animation, decremented afterwards. If zero, the interval timer is disabled
	this.timerID; // ID of the timer used for animating
	this.animations = []; // List of animations in progress
	return this;
}

// Start animation engine
Animator.prototype.startAnimating = function() // Variable number of arguments
{
	for(var t=0; t<arguments.length; t++)
		this.animations.push(arguments[t]);
	if(this.running == 0)
		{
		var me = this;
		this.timerID = window.setInterval(function() {me.doAnimate(me);},25);
		}
	this.running += arguments.length;
}

// Perform an animation engine tick, calling each of the known animation modules
Animator.prototype.doAnimate = function(me)
{
	var a = 0;
	while(a<me.animations.length)
		{
		var animation = me.animations[a];
		animation.progress += animation.step;
		if(animation.progress < 0 || animation.progress > 1)
			{
			animation.stop();
			me.animations.splice(a,1);
			if(--me.running == 0)
				window.clearInterval(me.timerID);
			}
		else
			{
			animation.tick();
			a++;
			}
		}
}

// Map a 0..1 value to 0..1, but slow down at the start and end
Animator.slowInSlowOut = function(progress)
{
	return(1-((Math.cos(progress * Math.PI)+1)/2));
}

// ---------------------------------------------------------------------------------
// Zoomer animation
// ---------------------------------------------------------------------------------

function Zoomer(text,startElement,targetElement,slowly)
{
	this.element = document.createElement("div");
	this.element.appendChild(document.createTextNode(text));
	this.element.className = "zoomer";
	document.body.appendChild(this.element);
	this.startElement = startElement;
	this.startLeft = findPosX(this.startElement);
	this.startTop = findPosY(this.startElement);
	this.startWidth = this.startElement.offsetWidth;
	this.startHeight = this.startElement.offsetHeight;
	this.targetElement = targetElement;
	this.targetLeft = findPosX(this.targetElement);
	this.targetTop = findPosY(this.targetElement);
	this.targetWidth = this.targetElement.offsetWidth;
	this.targetHeight = this.targetElement.offsetHeight;
	this.progress = 0;
	this.step = slowly ? config.animSlow : config.animFast;
	this.targetElement.style.opacity = 0;
	return this;
}

Zoomer.prototype.stop = function()
{
	this.element.parentNode.removeChild(this.element);
	this.targetElement.style.opacity = 1;
}

Zoomer.prototype.tick = function()
{
	var f = Animator.slowInSlowOut(this.progress);
	this.element.style.left = this.startLeft + (this.targetLeft-this.startLeft) * f + "px";
	this.element.style.top = this.startTop + (this.targetTop-this.startTop) * f + "px";
	this.element.style.width = this.startWidth + (this.targetWidth-this.startWidth) * f + "px";
	this.element.style.height = this.startHeight + (this.targetHeight-this.startHeight) * f + "px";
	this.element.style.display = "block";
	this.targetElement.style.opacity = this.progress;
	//this.targetElement.style.filter = "alpha(opacity:" + this.progress * 100 + ")";
}

// ---------------------------------------------------------------------------------
// Scroller animation
// ---------------------------------------------------------------------------------

function Scroller(targetElement,slowly)
{
	this.targetElement = targetElement;
	this.startScroll = findScrollY();
	this.targetScroll = ensureVisible(targetElement);
	this.progress = 0;
	this.step = slowly ? config.animSlow : config.animFast;
	return this;
}

Scroller.prototype.stop = function()
{
	window.scrollTo(0,this.targetScroll);
}

Scroller.prototype.tick = function()
{
	var f = Animator.slowInSlowOut(this.progress);
	window.scrollTo(0,this.startScroll + (this.targetScroll-this.startScroll) * f);
}

// ---------------------------------------------------------------------------------
// Slider animation
// ---------------------------------------------------------------------------------

// deleteMode - "none", "all" [delete target element and it's children], [only] "children" [but not the target element]
function Slider(element,opening,slowly,deleteMode)
{
	this.element = element;
	element.style.display = "block";
	this.deleteMode = deleteMode;
	this.element.style.height = "auto";
	this.realHeight = element.offsetHeight;
	this.opening = opening;
	this.step = slowly ? config.animSlow : config.animFast;
	if(opening)
		{
		this.progress = 0;
		element.style.height = "0px";
		element.style.display = "block";
		}
	else
		{
		this.progress = 1;
		this.step = -this.step;
		}
	element.style.overflow = "hidden";
	return this;
}

Slider.prototype.stop = function()
{
	if(this.opening)
		this.element.style.height = "auto";
	else
		{
		switch(this.deleteMode)
			{
			case "none":
				this.element.style.display = "none";
				break;
			case "all":
				this.element.parentNode.removeChild(this.element);
				break;
			case "children":
				removeChildren(this.element);
				break;
			}
		}
}

Slider.prototype.tick = function()
{
	var f = Animator.slowInSlowOut(this.progress);
	var h = this.realHeight * f;
	this.element.style.height = h + "px";
	this.element.style.opacity = f;
}

// ---------------------------------------------------------------------------------
// Augmented methods for the JavaScript Number(), Array() and String() objects
// ---------------------------------------------------------------------------------

// Clamp a number to a range
Number.prototype.clamp = function(min,max)
{
	c = this;
	if(c < min)
		c = min;
	if(c > max)
		c = max;
	return c;
}

// Find an entry in an array. Returns the array index or null
Array.prototype.find = function(item)
{
	var p = null;
	for(var t=0; t<this.length; t++)
		if(this[t] == item)
			{
			p = t;
			break;
			}
	return p;
}

// Push a new value into an array only if it is not already present in the array. If the optional unique parameter is false, it reverts to a normal push
Array.prototype.pushUnique = function(item,unique)
{
	if(unique != undefined && unique == false)
		this.push(item);
	else
		{
		if(this.find(item) == null)
			this.push(item);
		}
}

// Get characters from the right end of a string
String.prototype.right = function(n)
{
	if(n < this.length)
		return this.slice(this.length-n);
	else
		return this;
}

// Trim whitespace from both ends of a string
String.prototype.trim = function()
{
	var regexpTrim = new RegExp("^\\s*(.*)\\s*$","mg");
	return(this.replace(regexpTrim,"$1"));
}

// Convert a string from a CSS style property name to a JavaScript style name ("background-color" -> "backgroundColor")
String.prototype.unDash = function()
{
	var s = this.split("-");
	if(s.length > 1)
		for(var t=1; t<s.length; t++)
			s[t] = s[t].substr(0,1).toUpperCase() + s[t].substr(1);
	return s.join("");
}

// Substitute substrings from an array into a format string that includes '%1'-type specifiers
String.prototype.format = function(substrings)
{
	var subRegExp = new RegExp("(?:%(\\d+))","mg");
	var currPos = 0;
	var r = [];
	do {
		var match = subRegExp.exec(this);
		if(match && match[1])
			{
			if(match.index > currPos)
				r.push(this.substring(currPos,match.index));
			r.push(substrings[parseInt(match[1])]);
			currPos = subRegExp.lastIndex;
			}
	} while(match);
	if(currPos < this.length)
		r.push(this.substring(currPos,this.length));
	return r.join("");
}

// Escape any special RegExp characters with that character preceded by a backslash
String.prototype.escapeRegExp = function()
{
	return(this.replace(new RegExp("[\\\\\\^\\$\\*\\+\\?\\(\\)\\=\\!\\|\\,\\{\\}\\[\\]\\.]","g"),"\\$&"));
}

// Convert & to "&amp;", < to "&lt;", > to "&gt;" and " to "&quot;"
String.prototype.htmlEncode = function()
{
	var regexpAmp = new RegExp("&","mg");
	var regexpLessThan = new RegExp("<","mg");
	var regexpGreaterThan = new RegExp(">","mg");
	var regexpQuote = new RegExp("\"","mg");
	return(this.replace(regexpAmp,"&amp;").replace(regexpLessThan,"&lt;").replace(regexpGreaterThan,"&gt;").replace(regexpQuote,"&quot;"));
}

// Process a string list of macro parameters into an array. Parameters can be quoted with "", '', [[]] or left unquoted (and therefore space-separated)
String.prototype.readMacroParams = function()
{
	var regexpMacroParam = new RegExp("(?:\\s*)(?:(?:\"([^\"]*)\")|(?:'([^']*)')|(?:\\[\\[([^\\]]*)\\]\\])|([^\"'\\s]\\S*))","mg");
	var params = [];
	do {
		var match = regexpMacroParam.exec(this);
		if(match)
			{
			if(match[1]) // Double quoted
				params.push(match[1]);
			else if(match[2]) // Single quoted
				params.push(match[2]);
			else if(match[3]) // Double-square-bracket quoted
				params.push(match[3]);
			else if(match[4]) // Unquoted
				params.push(match[4]);
			}
	} while(match);
	return params;
}

// Process a string list of tiddler names into an array. Tiddler names that have spaces in them must be [[bracketed]]
String.prototype.readBracketedList = function(unique)
{
	var bracketedPattern = "\\[\\[([^\\]]+)\\]\\]";
	var unbracketedPattern = "[^\\s$]+";
	var pattern = "(?:" + bracketedPattern + ")|(" + unbracketedPattern + ")";
	var re = new RegExp(pattern,"mg");
	var tiddlerNames = [];
	do {
		var match = re.exec(this);
		if(match)
			{
			if(match[1]) // Bracketed
				tiddlerNames.pushUnique(match[1],unique);
			else if(match[2]) // Unbracketed
				tiddlerNames.pushUnique(match[2],unique);
			}
	} while(match);
	return(tiddlerNames);
}

// Static method to bracket a string with double square brackets if it contains a space
String.encodeTiddlyLink = function(title)
{
	if(title.indexOf(" ") == -1)
		return(title);
	else
		return("[[" + title + "]]");
}

// Static method to left-pad a string with 0s to a certain width
String.zeroPad = function(n,d)
{
	var s = n.toString();
	if(s.length < d)
		s = "000000000000000000000000000".substr(0,d-s.length) + s;
	return(s);
}

// ---------------------------------------------------------------------------------
// RGB colour object
// ---------------------------------------------------------------------------------

// Construct an RGB colour object from a '#rrggbb' or 'rgb(n,n,n)' string or from separate r,g,b values
function RGB(r,g,b)
{
	this.r = 0;
	this.g = 0;
	this.b = 0;
	if(typeof r == "string")
		{
		if(r.substr(0,1) == "#")
			{
			this.r = parseInt(r.substr(1,2),16)/255;
			this.g = parseInt(r.substr(3,2),16)/255;
			this.b = parseInt(r.substr(5,2),16)/255;
			}
		else
			{
			var rgbPattern = /rgb\s*\(\s*(\d{1,3})\s*,\s*(\d{1,3})\s*,\s*(\d{1,3})\s*\)/ ;
			var c = r.match(rgbPattern);
			if (c)
				{
				this.r = parseInt(c[1],10)/255;
				this.g = parseInt(c[2],10)/255;
				this.b = parseInt(c[3],10)/255;
				}
			}
		}
	else
		{
		this.r = r;
		this.g = g;
		this.b = b;
		}
	return this;
}

// Mixes this colour with another in a specified proportion
// c = other colour to mix
// f = 0..1 where 0 is this colour and 1 is the new colour
// Returns an RGB object
RGB.prototype.mix = function(c,f)
{
	return new RGB(this.r + (c.r-this.r) * f,this.g + (c.g-this.g) * f,this.b + (c.b-this.b) * f);
}

// Return an rgb colour as a #rrggbb format hex string
RGB.prototype.toString = function()
{
	var r = this.r.clamp(0,1);
	var g = this.g.clamp(0,1);
	var b = this.b.clamp(0,1);
	return("#" + ("0" + Math.floor(r * 255).toString(16)).right(2) +
				 ("0" + Math.floor(g * 255).toString(16)).right(2) +
				 ("0" + Math.floor(b * 255).toString(16)).right(2));
}

// ---------------------------------------------------------------------------------
// Augmented methods for the JavaScript Date() object
// ---------------------------------------------------------------------------------

// Substitute date components into a string
Date.prototype.formatString = function(template)
{
	template = template.replace(/YYYY/g,this.getFullYear());
	template = template.replace(/YY/g,String.zeroPad(this.getFullYear()-2000,2));
	template = template.replace(/MMM/g,config.messages.dates.months[this.getMonth()]);
	template = template.replace(/0MM/g,String.zeroPad(this.getMonth()+1,2));
	template = template.replace(/MM/g,this.getMonth()+1);
	template = template.replace(/DDD/g,config.messages.dates.days[this.getDay()]);
	template = template.replace(/0DD/g,String.zeroPad(this.getDate(),2));
	template = template.replace(/DD/g,this.getDate());
	template = template.replace(/hh/g,this.getHours());
	template = template.replace(/mm/g,this.getMinutes());
	template = template.replace(/ss/g,this.getSeconds());
	return template;
}

// Convert a date to UTC YYYYMMDDHHMM string format
Date.prototype.convertToYYYYMMDDHHMM = function()
{
	return(String.zeroPad(this.getFullYear(),4) + String.zeroPad(this.getMonth()+1,2) + String.zeroPad(this.getDate(),2) + String.zeroPad(this.getHours(),2) + String.zeroPad(this.getMinutes(),2));
}

// Convert a date to UTC YYYYMMDD.HHMMSSMMM string format
Date.prototype.convertToYYYYMMDDHHMMSSMMM = function()
{
	return(String.zeroPad(this.getFullYear(),4) + String.zeroPad(this.getMonth()+1,2) + String.zeroPad(this.getDate(),2) + "." + String.zeroPad(this.getHours(),2) + String.zeroPad(this.getMinutes(),2) + String.zeroPad(this.getSeconds(),2) + String.zeroPad(this.getMilliseconds(),4));
}

// Static method to create a date from a UTC YYYYMMDDHHMM format string
Date.convertFromYYYYMMDDHHMM = function(d)
{
	var theDate = new Date(parseInt(d.substr(0,4),10),
							parseInt(d.substr(4,2),10)-1,
							parseInt(d.substr(6,2),10),
							parseInt(d.substr(8,2),10),
							parseInt(d.substr(10,2),10),0,0);
	return(theDate);
}

// ---------------------------------------------------------------------------------
// DOM utilities - many derived from www.quirksmode.org 
// ---------------------------------------------------------------------------------

function drawGradient(place,horiz,colours)
{
	for(var t=0; t<= 100; t+=2)
		{
		var bar = document.createElement("div");
		place.appendChild(bar);
		bar.style.position = "absolute";
		bar.style.left = horiz ? t + "%" : 0;
		bar.style.top = horiz ? 0 : t + "%";
		bar.style.width = horiz ? (101-t) + "%" : "100%";
		bar.style.height = horiz ? "100%" : (101-t) + "%";
		bar.style.zIndex = -1;
		var f = t/100;
		var p = f*(colours.length-1);
		bar.style.backgroundColor = colours[Math.floor(p)].mix(colours[Math.ceil(p)],p-Math.floor(p)).toString();
		}
}

function createTiddlyText(theParent,theText)
{
	return theParent.appendChild(document.createTextNode(theText));
}

function createTiddlyElement(theParent,theElement,theID,theClass,theText)
{
	var e = document.createElement(theElement);
	if(theClass != null)
		e.className = theClass;
	if(theID != null)
		e.setAttribute("id",theID);
	if(theText != null)
		e.appendChild(document.createTextNode(theText));
	if(theParent != null)
		theParent.appendChild(e);
	return(e);
}

function createTiddlyButton(theParent,theText,theTooltip,theAction,theClass,theId,theAccessKey)
{
	var theButton = document.createElement("a");
	theButton.className = "button";
	if(theAction)
		{
		theButton.onclick = theAction;
		theButton.setAttribute("href","#");
		}
	theButton.setAttribute("title",theTooltip);
	if(theText)
		theButton.appendChild(document.createTextNode(theText));
	if(theClass)
		theButton.className = theClass;
	if(theId)
		theButton.id = theId;
	if(theParent)
		theParent.appendChild(theButton);
	if(theAccessKey)
		theButton.setAttribute("accessKey",theAccessKey);
	return(theButton);
}

function createTiddlyLink(place,title,includeText)
{
	var text = includeText ? title : null;
	var subTitle, theClass;
	if(store.tiddlerExists(title))
		{
		subTitle = store.tiddlers[title].getSubtitle();
		theClass = "tiddlyLinkExisting tiddlyLink";
		}
	else
		{
		subTitle = config.messages.undefinedTiddlerToolTip.format([title]);
		theClass = "tiddlyLinkNonExisting tiddlyLink";
		}
	var btn = createTiddlyButton(place,text,subTitle,onClickTiddlerLink,theClass);
	btn.setAttribute("tiddlyLink",title);
	return(btn);
}

function createExternalLink(place,url)
{
	var theLink = document.createElement("a");
	theLink.className = "externalLink";
	theLink.href = url;
	theLink.title = config.messages.externalLinkTooltip.format([url]);
	if(config.options.chkOpenInNewWindow)
		theLink.target = "_blank";
	place.appendChild(theLink);
	return(theLink);
}

// Cross-browser event handler attachment
function addEvent(element,type,fn)
{
	if (element.addEventListener)
		{
		element.addEventListener(type,fn,false);
		return true;
		}
	else if (element.attachEvent)
		{
		var r = element.attachEvent("on" + type,fn);
		return r;
		}
	else
		return false;
}

// Cross-browser event handler removal
function removeEvent(element,type,fn)
{
	if (element.removeEventListener)
		{
		element.removeEventListener(type,fn,false);
		return true;
		}
	else if (element.detachEvent)
		{
		var r = element.detachEvent("on" + type,fn);
		return r;
		}
	else
		return false;
}

// Find the tiddler instance (if any) containing a specified element
function findContainingTiddler(e)
{
	if(e == null)
		return(null);
	do {
		if(e != document)
			{
			if(e.id)
				if(e.id.substr(0,7) == "tiddler")
					return(e);
			}
		e = e.parentNode;
	} while(e != document);
	return(null);
}

// Resolve the target object of an event
function resolveTarget(e)
{
	var obj;
	if (e.target)
		obj = e.target;
	else if (e.srcElement)
		obj = e.srcElement;
	if (obj.nodeType == 3) // defeat Safari bug
		obj = obj.parentNode;
	return(obj);
}

// Return the content of an element as plain text with no formatting
function getElementText(elementID)
{
	var e = document.getElementById(elementID);
	var text = "";
	if(e.innerText)
		text = e.innerText;
	else if(e.textContent)
		text = e.textContent;
	return text;
}

// Get the scroll position for window.scrollTo necessary to scroll a given element into view
function ensureVisible(e)
{
	var posTop = findPosY(e);
	var posBot = posTop + e.offsetHeight;
	var winTop = findScrollY();
	var winHeight = findWindowHeight();
	var winBot = winTop + winHeight;
	if(posTop < winTop)
		return(posTop);
	else if(posBot > winBot)
		{
		if(e.offsetHeight < winHeight)
			return(posTop - (winHeight - e.offsetHeight));
		else
			return(posTop);
		}
	else
		return(winTop);
}

// Get the current height of the display window
function findWindowHeight()
{
	return(window.innerHeight ? window.innerHeight : document.body.clientHeight);
}

// Get the current vertical page scroll position
function findScrollY()
{
	return(window.scrollY ? window.scrollY : document.body.scrollTop);
}

function findPosX(obj)
{
	var curleft = 0;
	while (obj.offsetParent)
		{
		curleft += obj.offsetLeft;
		obj = obj.offsetParent;
		}
	return curleft;
}

function findPosY(obj)
{
	var curtop = 0;
	while (obj.offsetParent)
		{
		curtop += obj.offsetTop;
		obj = obj.offsetParent;
		}
	return curtop;
}

// Create a non-breaking space
function insertSpacer(place)
{
	var e = document.createTextNode(String.fromCharCode(160));
	if(place)
		place.appendChild(e);
	return e;
}

// Remove all children of a node
function removeChildren(e)
{
	while(e.hasChildNodes())
		e.removeChild(e.firstChild);
}

// Add a stylesheet, replacing any previous custom stylesheet
function setStylesheet(s,id)
{
	if(!id)
		id = "customStyleSheet";
	var n = document.getElementById(id);
	if(document.createStyleSheet) // Test for IE's non-standard createStyleSheet method
		{
		if(n)
			n.parentNode.removeChild(n);
		// This failed without the &nbsp;
		document.body.insertAdjacentHTML("beforeEnd","&nbsp;<style id='" + id + "'>" + s + "</style>");
		}
	else
		{
		if(n)
			n.replaceChild(document.createTextNode(s),n.firstChild);
		else
			{
			var n = document.createElement("style");
			n.type = "text/css";
			n.id = id;
			n.appendChild(document.createTextNode(s));
			document.getElementsByTagName("head")[0].appendChild(n);
			}
		}
}

// ---------------------------------------------------------------------------------
// End of scripts
// ---------------------------------------------------------------------------------

</script>
<style type="text/css">

body {
	background-color: #ffffff;
	font-size: 9pt;
	font-family: verdana,arial,helvetica;
	margin: 0em 0em 0em 0em;
	padding: 0em 0em 0em 0em;
	position: relative;
	z-index: 0;
}

img {
	border: none;
}

a:link, a:visited {
	text-decoration: none;
}

a:hover, a:active {
	text-decoration: none;
}

#contentWrapper {
	position: relative;
}

#header {
}

#titleLine {
	color: #ffffff;
	background-color: #330000;
	padding: 5em 1em 1em 1em;
}

#titleLine a {
	color: #CCFF66;
}

#siteTitle {
	font-size: 26pt;
}

#siteSubtitle {
	padding-left: 1em;
	font-size: 10pt;
}

#mainMenu {
	position: absolute;
	left: 0em;
	width: 10em;
	line-height: 166%;
	padding: 1.5em 0.5em 0.5em 0.5em;
	font-size: 10pt;
	color: black;
	text-align: right;
}

#mainMenu .tiddlyLink {
	color: #996633;
}

#mainMenu .tiddlyLink:hover {
	background-color: #996633;
	color: #ffffff;
}

#mainMenu .externalLink {
	color: #996633;
	text-decoration: underline;
}

#mainMenu .externalLink:hover {
	background-color: #996633;
	color: #ffffff;
}

#mainMenu .button {
	color: #993300;
}

#mainMenu .button:hover {
	color: #ccff66;
	background-color: #993300;
}

#displayArea {
	margin: 1em 17em 0em 14em;
}

#tiddlerDisplay {
}

#messageArea {
	background-color: #993300;
	color: #ffffff;
	padding: 0.5em 0.5em 0.5em 0.5em;
	display: none;
}

#messageArea a:link, #messageArea a:visited {
	display: inline;
	text-decoration: underline;
	color: #cc9900;
}

#messageArea a:hover {
	color: #996633;
}

#messageArea a:active {
	color: #ffffff;
}

#popup {
	display: none;
	position: absolute;
	line-height: 110%;
	font-size: 8pt;
	color: #ccff66;
	background-color: #993300;
	padding: 0.25em 0.25em 0.25em 0.25em;
	border-right: 1px solid #330000;
	border-bottom: 1px solid #330000;
	z-index: 10;
}

#popup a {
	display: block;
	color: #ccff66;
	padding: 1px 1px 1px 1px;
}

#popup a:hover {
	background-color: #ccff66;
	color: #330000;
}

#popup hr {
	border-top: solid 1px #ccff66;
	border-left: none;
	border-right: none;
	border-bottom: none;
	height: 1px;
	width: 5em;
	left: 0em;
	color: #ccff66;
}

.tabset {
	padding: 1em 0em 0em 0.5em;
}

.tab {
	margin: 0em 0em 0em 0.25em;
	padding: 2px 2px 2px 2px;
}

.tabSelected {
	background-color: #eeeeaa;
}

.tabUnselected {
	background-color: #cc9900;
}

.tab:hover {
}

.tab:active {
}

.tabContents {
	padding: 0.5em 0.5em 0.5em 0.5em;
	background-color: #eeeeaa;
}

.tabContents ul, .tabContents ol {
	margin: 0;
	padding: 0;
}

.tabContents li {
	list-style: none;
}

.tabContents li.listLink {
   margin-left: .75em;
}

.tiddler {
	padding: 0em 0em 0em 0em;
}

.selectedTiddler {
	padding: 1em 1em 0em 1em;
	font-size: 9pt;
}

.unselectedTiddler {
	padding: 1em 1em 0em 1em;
	font-size: 9pt;
}

.tiddler a.tiddlyLinkExisting {
	font-weight: bold;
}

.tiddler a.tiddlyLinkNonExisting {
	font-style: italic;
}

.tiddler a.externalLink {
	text-decoration: underline;
}

.tiddler .button {
	padding: 0.2em 0.4em 0.2em 0.4em;
	color: #993300;
}

.tiddler .button:hover {
	text-decoration: none;
	color: #ccff66;
	background-color: #993300;
}

.tiddler .button:active {
	color: #ffffff;
	background-color: #cc9900;
}

.title {
	font-size: 10pt;
	font-weight: bold;
}

.selectedTiddler .title {
}

.toolbar {
	text-align: right;
	font-weight: normal;
	font-size: 8pt;
	padding: 0em 0em 0em 2em;
	color: #aaaaaa;
	visibility: hidden;
}

.toolbar #popup {
	text-align: left;
}

.selectedTiddler .toolbar {
	visibility: visible;
}

.footer {
	clear: left;
	clear: right;
	font-weight: normal;
	font-size: 8pt;
	margin: 0em 0em 0em 0em;
	padding: 0em 0em 0em 0em;
	color: #dddddd;
}

.selectedTiddler .footer {
	color: #888888;
}

.body {
	padding-top: 0.5em;
}

.viewer {
	color: #000000;
	line-height: 140%;
}

.viewer a:link, .body a:visited {
	color: #996633;
}

.viewer a:hover {
	color: #ffffff;
	background-color: #996633;
}

.viewer .button {
	margin: 0em 0.25em 0em 0.25em;
	padding: 0em 0.25em 0em 0.25em;
	background-color: #cc9900;
	color: #330000;
	border-right: 1px solid #33000;
	border-bottom: 1px solid #33000;
}

.viewer .button:hover {
	background-color: #eeeeaa;
	color: #cc9900;
}

.viewer blockquote {
	font-size: 8pt;
	line-height: 150%;
	border-left: 3px solid #666666;
	padding-left: 0.8em;
	margin-left: 2.5em;
}

.viewer ul {
	margin-left: 0.5em;
	padding-left: 1.5em;
}

.viewer ol {
	margin-left: 0.5em;
	padding-left: 1.5em;
}

.viewer h1,.viewer h2,.viewer h3,.viewer h4,.viewer h5 {
	font-weight: bold;
	text-decoration: none;
	background-color: #cccc99;
	padding-left: 0.4em;
}

.viewer h1 {
	font-size: 12pt;
}

.viewer h2 {
	font-size: 11pt;
}

.viewer h3 {
	font-size: 10pt;
}

.viewer h4 {
	font-size: 9pt;
}

.viewer h5 {
	font-size: 8pt;
}

.viewer table {
	border-collapse: collapse;
	border: 2px solid #303030;
	margin-left: 1.0em;
	margin-right: 1.0em;
	margin-top: 0.8em;
	margin-bottom: 0.8em;
	font-size: 100%;
}

.viewer th {
	background-color: #999966;
	border: 1px solid #606060;
	color: #ffffff;
	padding: 3px;
}

.viewer td, .viewer tr {
	border: 1px solid #606060;
	padding: 3px;
}

.viewer caption {
	padding: 3px;
}

.viewer pre {
	padding: 0.5em 0.5em 0.5em 0.5em;
	margin-left: 0.5em;
	font-size: 100%;
	line-height: 1.4em;
	color: #000000;
	border: 1px solid #996633;
	background-color: #eeeeaa;
	overflow: auto;
}

.viewer code {
	font-size: 100%;
	line-height: 1.4em;
	color: #663300;
}

.viewer hr {
	border-top: dashed 1px #606060;
	border-left: none;
	border-right: none;
	border-bottom: none;
	height: 1px;
	color: #666666;
}

.highlight, .marked {
	color: #000000;
	background-color: #ffe72f;
}

.editor {
	font-size: 8pt;
	color: #402C74;
	font-weight: normal;
}

.editor input {
	display: block;
	border: 1px solid black;
	width: 100%;
}

.editor textarea {
	display: block;
	font: inherit;
	border: 1px solid black;
	width: 100%;
}

.editorFooter {
	padding: 0.25em 0em 0.25em 0em;
	font-size: 8pt;
	color: #aaaaaa;
}

.editorFooter A {
	padding: 0.2em 0.4em 0.2em 0.4em;
	color: #993300;
}

.editorFooter A:hover {
	text-decoration: none;
	color: #ccff66;
	background-color: #993300;
}

.editorFooter A:active {
	color: #ffffff;
	background-color: #cc9900;
}

#sidebar {
	position: absolute;
	right: 0em;
	width: 16em;
	color: #000000;
	font-size: 8pt;
}

#sidebarOptions {
	padding-top: 0em;
	background-color: #cc9900;
}

#sidebarOptions .button {
	color: #993300;
	padding: 0.3em 0.2em 0.3em 1em;
	display: block;
}

#sidebarOptions .button:hover {
	color: #ccff66;
	background-color: #993300;
}

#sidebarOptions .button:active {
	color: #993300;
	background-color: #ccff66;
}

#sidebarOptions input {
	margin: 0.4em 0em 0.3em 1em;
}

#sidebarOptions .sliderPanel {
	padding: 0.5em 0.5em 0.5em 0.5em;
	font-size: 7pt;
	background-color: #eeeeaa;
}

#sidebarOptions .sliderPanel A {
	color: #993300;
	font-weight: bold;
}

#sidebarOptions .sliderPanel A:hover {
	color: #ccff66;
	background-color: #993300;
}

#sidebarOptions .sliderPanel A:active {
	color: #993300;
	background-color: #ccff66;
}

#sidebarOptions .sliderPanel input {
	margin: 0em 0em 0.3em 0em;
}

.sidebarSubHeading {
	font-size: 7pt;
	color: #330000;
}

#sidebarTabs {
	background-color: #cc9900;
}

#sidebarTabs .tabSelected {
	color: #ccff66;
	background-color: #996633;
	position: relative;
	top: -2px;
}

#sidebarTabs .tabUnselected {
	color: #ccff66;
	background-color: #993300;
}

#sidebarTabs .tabContents {
	background-color: #996633;
	width: 16em;
	white-space: nowrap;
	overflow: hidden;
}

#sidebarTabs .txtMoreTab .tabSelected {
	background-color: #993300;
}

#sidebarTabs .txtMoreTab .tabUnselected {
	background-color: #330000;
}

#sidebarTabs .txtMoreTab .tabContents {
	background-color: #993300;
}

#sidebarTabs .tabContents .tiddlyLink {
	color: #ccff66;
}

#sidebarTabs .tabContents .tiddlyLink:hover {
	background-color: #ccff66;
	color: #330000;
}

#sidebarTabs .tabContents .button {
	color: #ccff66;
	padding: 0em 0em 0em 0em;
	display: inline;
}

#sidebarTabs .tabContents .button:hover {
	color: #330000;
	background-color: #ccff66;
}

#licensePanel {
	padding: 0.5em 0em 0.5em 0em;
}

#licensePanel A {
	display: block;
	padding: 0.2em 0.2em 0.2em 0.2em;
	color: #993300;
}

#licensePanel A:hover {
	text-decoration: none;
	color: #ccff66;
	background-color: #993300;
}

#licensePanel A:active {
	color: #993300;
	background-color: #ccff66;
}

#storeArea, #copyright {
	display: none;
}

.sparkline {
	background-color: #eeeeaa;
	border: none;
	line-height: 100%;
}

.sparktick {
	background-color: #993300;
	outline: 0;
}

.errorNoSuchMacro {
	color: #ffff00;
	background-color: #ff0000;
}

.zoomer {
	font-size: 10pt;
	display: none;
	color: #996633;
	position: absolute;
	padding: 1em 1em 1em 1em;
	border: 1px solid #996633;
}

#saveTest {
	display: none;
}

@media print {

#mainMenu, #sidebar, #messageArea {
	display: none ! important;
}

#displayArea {
	margin: 1em 1em 0em 1em;
}

}

</style>
<noscript>
<style type="text/css">

#contentWrapper {
	display: none;
}

#storeArea {
	display: block;
	margin: 4em 17em 3em 17em;
}

#storeArea div {
 padding: 0.5em; 0.5em; 0.5em; 0.5em;
 margin: 1em 0em 0em 0em;
 border-color: #f0f0f0 #606060 #404040 #d0d0d0;
 border-style: solid;
 border-width: 2px;
 height: 7em;
 overflow: auto;
}

#javascriptWarning {
	width: 100%;
	text-align: center;
	font-weight: bold;
	background-color: #dd1100;
	color: #ffffff;
	padding:1em 0em 1em 0em;
}

</style>
</noscript>
</head>
<body onload="main();" onunload="if(checkUnsavedChanges) checkUnsavedChanges();">
	<script>
	if (detectPlugin("TiddlyWiki Saver"))
		{
		document.write('<embed style="display: none" name="tiddlyWikiSafariSaver" width="0" height="0" type="application/x-webkit-tiddlywiki-saver"></embed>'); 
		saveUsingSafari = true;
		}
	</script>
	<div id="copyright">
	Welcome to TiddlyWiki by Jeremy Ruston, Copyright &copy; 2005 Osmosoft Limited
	</div>
	<noscript>
		<div id="javascriptWarning">This page requires JavaScript to function properly</div>
	</noscript>
	<div id="saveTest"></div>
	<div id="contentWrapper">
		<div id="header">
			<div id="titleLine">
				<span id="siteTitle"></span>
				<span id="siteSubtitle"></span>
			</div>
		</div>
		<div id="sidebar">
			<div id="sidebarOptions"></div>
			<div id="sidebarTabs"></div>
		</div>
		<div id="mainMenu"></div>
		<div id="displayArea">
			<div id="messageArea"></div>
			<div id="tiddlerDisplay"></div>
		</div>
	</div>
	<div id="storeArea"><div tiddler="AdvancedOptions" modified="200509291525" modifier="Pavel" tags="">&lt;&lt;option chkOpenInNewWindow&gt;&gt; OpenLinksInNewWindow\n&lt;&lt;option chkSaveEmptyTemplate&gt;&gt; SaveEmptyTemplate\n&lt;&lt;option chkToggleLinks&gt;&gt; Clicking on links to tiddlers that are already open causes them to close\n^^(override with Control or other modifier key)^^\n&lt;&lt;option chkHttpReadOnly&gt;&gt; HideEditingFeatures when viewed over HTTP\n&lt;&lt;option chkForceMinorUpdate&gt;&gt; Treat edits as MinorChanges by preserving date and time\n^^(override with Shift key when clicking 'done' or by pressing Ctrl-Shift-Enter^^</div>
<div tiddler="DefaultTiddlers" modified="200509301520" modifier="Pavel" tags="systemTiddlers">[[Начало]]\n[[Справка]]</div>
<div tiddler="MainMenu" modified="200509301639" modifier="Pavel" tags="systemTiddlers">[[Начало]][[Справка]][[Ссылки]]\n----\n\n[[Все тэги]][[Все записи]]\n----\n\n&lt;&lt;newTiddler&gt;&gt;&lt;&lt;newJournal &quot;DD MMM YYYY&quot;&gt;&gt;\n\n~~[[настроить меню|MainMenu]]~~~~версия &lt;&lt;version&gt;&gt;~~\n</div>
<div tiddler="OpenAll" modified="200509301610" modifier="Pavel" tags="systemConfig [[Macro / Plugin]]">/*\n{{{\n*/\n// ---------------------------------------------------------------------------------\n// openAll plug-in\n// ---------------------------------------------------------------------------------\nversion.extensions.openAll = {major: 0, minor: 1, revision: 1, date: new Date(&quot;Sep 1, 2005&quot;)};\nconfig.macros.openAll = {}\nconfig.macros.openAll.handler = function(place,macroName,params)\n{\n	var title = &quot;Open all &quot; + params[0];\n	var closeAllFirst = &quot;&quot;;\n	var limit = 10000;\n	var reverseOrder = &quot;&quot;;\n	for(i=1; i&lt;params.length; i++) { // Skip the first param\n		if(params[i]==&quot;closeAllFirst&quot;) closeAllFirst = &quot;closeAllFirst&quot;;\n		if(params[i]==&quot;reverseOrder&quot;) reverseOrder = &quot;reverseOrder&quot;;\n		if(params[i].substring(0,6)==&quot;limit:&quot;) limit = parseInt(params[i].substring(6));\n		if(params[i].substring(0,6)==&quot;title:&quot;) title = params[i].substring(6);\n	}\n	var openAll = createTiddlyButton(place,title,null,onClickOpenAllMacro);\n	openAll.setAttribute(&quot;tag&quot;,params[0]);\n	openAll.setAttribute(&quot;closeAllFirst&quot;,closeAllFirst);\n	openAll.setAttribute(&quot;limit&quot;,limit);\n	openAll.setAttribute(&quot;reverseOrder&quot;,reverseOrder);\n}\n\n// Event handler for 'openAll' macro\nfunction onClickOpenAllMacro(e)\n{\n	if (!e) var e = window.event;\n	var tag = this.getAttribute(&quot;tag&quot;);\n	var limit = this.getAttribute(&quot;limit&quot;);\n	var tagged = store.getTaggedTiddlers(tag);\n	if(this.getAttribute(&quot;closeAllFirst&quot;)==&quot;closeAllFirst&quot;) closeAllTiddlers();\n	if(this.getAttribute(&quot;reverseOrder&quot;)==&quot;reverseOrder&quot;) {\n		var t=tagged.length-limit;\n		if(t&lt;0) t=0;\n		for(; t&lt;tagged.length &amp;&amp; limit&gt;0; t++) {\n			displayTiddler(this,tagged[t].title,0,null,null,false,e.shiftKey || e.altKey);\n		}\n	}else{\n		for(var t=tagged.length-1; t&gt;=0 &amp;&amp; limit&gt;0; limit--,t--)\n			displayTiddler(this,tagged[t].title,0,null,null,false,e.shiftKey || e.altKey);\n	}\n	e.cancelBubble = true;\n	if (e.stopPropagation) e.stopPropagation();\n	return(false);\n}\n\n/*\n}}}\n*/</div>
<div tiddler="OptionsPanel" modified="200509291528" modifier="Pavel" tags="systemTiddlers">Имя, которым будут подписаны все записи. Используйте WikiWord.\n&lt;&lt;option txtUserName&gt;&gt;\n&lt;&lt;option chkPreviewEditor&gt;&gt; Preview Editor\n\n&lt;&lt;option chkSaveBackups&gt;&gt; Сохранять бэкапы\n&lt;&lt;option chkAutoSave&gt;&gt; Автосохранение\n&lt;&lt;option chkGenerateAnRssFeed&gt;&gt; Создавать RSS-ленту\n&lt;&lt;option chkRegExpSearch&gt;&gt; Поиск с Регэкспами\n&lt;&lt;option chkCaseSensitiveSearch&gt;&gt; Регистрозависимый поиск \n\n&lt;&lt;option chkAnimate&gt;&gt; Разрешить анимацию\n\nОткрыть AdvancedOptions</div>
<div tiddler="PreView" modified="200509301611" modifier="Pavel" tags="systemConfig [[Macro / Plugin]]">/*\n{{{\n*/\n\nif (config.options.chkPreviewEditor==undefined)\n	config.options.chkPreviewEditor=false;\n\nwindow.createTiddler = (function (create) {\n return function(place,before,title,state,highlightText,highlightCaseSensitive)\n{\n   if (2 == state&amp;&amp;config.options.chkPreviewEditor) { // Editor\n     var theTiddler = createTiddlerSkeleton(place,before,title);\n     createTiddlerTitle(title,highlightText,highlightCaseSensitive);\n     var theViewer = document.getElementById(&quot;viewer&quot; + title);\n     var theEditor = document.getElementById(&quot;editorWrapper&quot; + title);\n     if(!theEditor) {\n       createTiddlerToolbar(title,true);\n       createTiddlerEditor(title);\n       createTiddlerFooter(title,true);\n     }\n     return(theTiddler);\n   }\n   else {\n     return create(place,before,title,state,highlightText,highlightCaseSensitive);\n   }\n };\n})(window.createTiddler);\n\nwindow.createTiddlerEditor = (function(create) {\n\n function onEditChangeFunc(title) {\n   return function(event) {\n     var viewer = document.getElementById('viewer' + title);\n     removeChildren(viewer);\n     wikify(this.value, viewer, false, false);\n   };\n }\n\n return function(title) {\n   create(title);\n if (config.options.chkPreviewEditor)\n   document.getElementById('editorBody' + title).onkeypress = onEditChangeFunc(title);\n };\n})(window.createTiddlerEditor);\n\n/*\n}}}\n*/</div>
<div tiddler="SiteSubtitle" modified="200507121318" modifier="JeremyRuston" tags="systemTiddlers">a reusable non-linear personal web notebook</div>
<div tiddler="SiteTitle" modified="200509212109" modifier="JeremyRuston" tags="systemTiddlers">TiddlyWiki</div>
<div tiddler="SiteUrl" modified="200507121318" modifier="JeremyRuston" tags="systemTiddlers">http://www.tiddlywiki.com/</div>
<div tiddler="StyleSheet" modified="200509301635" modifier="Pavel" tags="">/* \nвзято с http://15black.bluedepot.com/styles/misttiddlywiki.html\n{{{\n */\n#popup{\n padding-left: 2px !important;\n padding-bottom: 2px !important;\n}\n\n#popup *{\n border: 0 !important;\n}\n\n#popup hr {\n border-top: solid 1px #ccc !important; \n border-left: none;\n border-right: none;\n border-bottom: none;\n height: 1px;\n color: #ccc;\n width: 98%;\n}\n\n#popup a:hover{\n color: black !important;\n}\n\nbody {\n margin: 0px;\n background-color: #e4e4e4;\n font-size: 9pt;\n font-family: tahoma,arial,helvetica;\n}\n\na:link, a:visited, a:hover, a:active {\n text-decoration: none;\n}\n\n#header {\n border-bottom: 1px solid #458;\n margin-bottom: 0em;\n}\n\n#titleLine {\n color: #fff;\n background: #bcd;\n padding: 0.7em 1em 1em 1em;\n}\n\n#titleLine a {\n text-decoration: none;\n color: #9ab;\n}\n\n#siteTitle {\n font-size: 40pt;\n font-weight: bold;\n padding-left: 20px;\n color: #9ab;\n}\n\n#siteSubtitle {\n font-size: 12pt;\n font-family: georgia,times;\n font-style: italic;\n color: #457;\n display: block;\n position: relative;\n bottom: 5px;\n left: 0px;\n padding-left: 70px;\n}\n\n#mainMenu {\n font-size: 12px;\n float: left;\n width: 13em;\n border: 1px solid #aaa;\n margin: .5em 1em .5em 1em;\n background: #f3f3f3;\n line-height: 125%;\n color: black;\n text-align: right;\npadding: 0;\n}\n\n#mainMenu .tiddlyLink, #mainMenu a.button{\n display: block; \n text-decoration: none;\n width: 12em;\n padding: .25em .5em;\n color: #444;\n}\n\n#mainMenu a:hover {\n color: #000 !important;\n background-color: #bcd !important;\n}\n\n#displayArea {\n margin: 1em 14em 0em 15em;\n}\n\n#messageArea {\n background-color: #5a84ad;\n color: #fff;\n padding: 0.5em 0.5em 0.5em 0.5em;\n margin: 0em 0em 0.6em 0em;\n border-bottom: 1px solid #458;\n display: none;\n}\n\n#messageArea a:link, #messageArea a:visited {\n display: inline;\n text-decoration: underline;\n color: #ddf;\n}\n\n#messageArea a:hover, #messageArea a:active{\n color: #fff;\n}\n\n.tiddler {\n border: 1px solid #aaa;\n margin: 0 10px 20px;\n padding: 8px;\n padding-top:0;\n font-family: arial,georgia,times;\n background-color: white;\n width: auto;\n overflow: hidden;\n}\n\n.innerTiddler {\n padding: 0.7em 1em 1em 0.8em;\n font-size: 9pt;\n}\n\n#displayArea .tiddlyLinkExisting {\n font-weight: bold;\n}\n\n#displayArea .tiddlyLinkNonExisting {\n font-style: italic;\n}\n\n#displayArea .externalLink {\n text-decoration: underline;\n}\n.title {\n font-family: tahoma,arial,helvetica;\n font-size: 13pt;\n color: #469;\n font-weight: bold;\n }\n\n.toolbar {\n font-family: tahoma,arial,helvetica;\n font-weight: normal;\n font-size: 8pt;\n padding: 0em 0em 0em 1em;\n color: #aaa !important;\n visibility: hidden;\n}\n\n.toolbar a{\n padding: 0.2em 0.4em 0.2em 0.4em;\n color: #888 !important;\n}\n\n.toolbar a:hover{\n color: black;\n background-color: #e4e4e4 !important;\n border: 1px solid #aaa !important;\n margin-left: -1px; \n margin-right: -1px;\n}\n\n.toolbar a:active{\n color: #666;\n}\n\n.viewer a.button{\n border: 0;\n background-color: transparent !important;\n padding: 0em;\n color: #888 !important;\n border: 1px solid transparent;\n}\n\n.editorFooter a:hover, .footer a.button {\n color: #888 !important;\n}\n\n.editorFooter a:hover, .footer a:hover{\n color: black;\n background-color: #e4e4e4 !important;\n border: 1px solid #aaa !important;\n margin-left: -1px; \n margin-right: -1px;\n}\n\n.viewer a.button:hover{\n color: black;\n background-color: #e4e4e4 !important;\n border: 1px solid #aaa !important;\n}\n\n.viewer a.button,.editorFooter a:hover, .footer a.button {\n color: #666;\n}\n\n#popup {\n display: none;\n position: absolute;\n top: 1.5em;\n left: 13.25em;\n font-size: 8pt;\n color: #888;\n background-color: #e4e4e4;\n padding: 0;\n border-top: 1px solid #aaa;\n border-bottom: 1px solid #330000;\n border-right: 1px solid #330000;\n border-left: 1px solid #aaa;\n}\n\n#popup a {\n display: block;\n color: #888;\n min-width: 8em;\n border: 0;\n margin: 0;\n}\n\n#popup a:hover {\n background-color: #e4e4e4;\n color: black;\n}\n\n.body {\n border-top:1px solid #ccc;\n padding-top: 0.5em;\n margin-top:0.3em;\n overflow: hidden;\n}\n\n.viewer {\n color: black;\n line-height: 140%;\n}\n\n.viewer a:link, .body a:visited{\n color: #922;\n}\n\n.viewer a:hover {\n color: #b44;\n background-color: transparent;\n text-decoration: none;\n}\n\n.viewer blockquote {\n font-size: 8pt;\n line-height: 150%;\n border-left: 1px solid #ccc;\n padding-left: 0.8em;\n margin-left: 2.5em;\n}\n\n.viewer ul {\n margin-left: 0.5em;\n padding-left: 1.5em;\n}\n\n.viewer ol {\n margin-left: 0.5em;\n padding-left: 1.5em;\n}\n\n/*==============================================Headings================*/\n\n.viewer h1,.viewer h2,h3,h4,h5,h6 {\n font-weight: bold;\n text-decoration: none;\n color: #469;\n padding-left: .6em;\nbackground-color: transparent !important;\nborder-bottom: 3px dotted #ccc;\n}\n\n.viewer h2 {\n font-size: 12pt;\n}\n\n.viewer h3 {\n font-size: 11pt;\n}\n\n.viewer h4 {\n font-size: 10pt;\n}\n\n.viewer h5 {\n font-size: 9pt;\n}\n\n.viewer h6 {\n font-size: 8pt;\n}\n\n.viewer table {\n font-size: 10pt;\n border-collapse: collapse;\n border: 2px solid #303030;\n margin-left: 1.0em;\n margin-right: 1.0em;\n margin-top: 0.8em;\n margin-bottom: 0.8em;\n}\n\n.viewer th {\n background-color: #bcd;\n border: 1px solid #606060;\n padding: 3px;\n}\n\n.viewer td, tr {\n border: 1px solid #606060;\n padding: 3px;\n}\n\n.viewer caption {\n font-size: smaller;\n padding: 3px;\n}\n\n.viewer hr {\n border-top: dashed 1px #606060;\n border-left: none;\n border-right: none;\n border-bottom: none;\n height: 1px;\n color: #666666;\n}\n\n.highlight {\n color: #000000;\n background-color: #bcd;\n}\n\n.editor {\n font-size: 8pt;\n color: #402c74;\n font-weight: normal;\n}\n\n.editor input {\n display: block;\n border: 1px solid black;\n}\n\n.editor textarea {\n display: block;\n font: inherit;\n border: 1px solid black;\n}\n\n/*\n=================Sidebar==========\n=================================\n*/\n\n\n#sidebar {\n float: right;\n width: 14em;\n font-size: 8pt;\n border-left: 1px solid #aaa;\n border-bottom:1px solid #aaa;\n}\n\n#sidebarOptions {\n color: #666 !important;\n background-color: #f3f3f3 !important;\n}\n\n#sidebar #sidebarOptions a:hover{\n background-color: #f3f3f3;\n}\n\n#contentWrapper #sidebar a:hover{\n color: #b44;\n text-decoration: underline;\n}\n\n#contentWrapper .sidebarSubHeading {\n font-size: 0.95em;\n color: #236;\n}\n\n#contentWrapper #commandPanel {\n padding-top: 0.5em;\n background-color: #f3f3f3;\n color: black;\n font-size: 8pt;\n}\n\n#contentWrapper #commandPanel a {\n display: block;\n padding: 0.3em 0.2em 0.3em 1em;\n color: #666;\n text-decoration: none;\n}\n\n#contentWrapper #commandPanel a:hover {\n color: #922;\n text-decoration: underline;\n background-color: transparent;;\n}\n\n#contentWrapper #commandPanel input {\n margin: 0.4em 0em 0.3em 1em;\n border: 1px solid black;\n}\n\n#contentWrapper #optionsPanel {\n display: none;\n background-color: #f3f8ff;\n padding: 0.5em 0.5em 0em 0.5em;\n font-size: 7pt;\n color: black;\n}\n\n#contentWrapper #optionsPanel a:link, #optionsPanel a:visited {\n color: #666;\n font-weight: bold;\n}\n\n#contentWrapper #optionsPanel a:hover {\n color: #922;\n text-decoration: underline;\n background-color: transparent;\n}\n\n.optionsText {\n margin-top: 0.25em;\n margin-bottom: 0.75em;\n}\n\n.optionsItem {\n}\n/*========================================================================*/\n#contentWrapper #sidebarTabs {\n background-color: #f3f3f3;\n padding: 0em;\n}\n\n#contentWrapper #sidebarTabs a {\n color: black;\n background-color: transparent;\n}\n\n#contentWrapper #sidebarTabs a:hover {\n color: #922; text-decoration: underline;\n background-color: transparent;\n}\n\n#contentWrapper #sidebarTabs a:active {\n color: black;\n}\n\n#contentWrapper .tabContentTags #popup {\n display: none;\n position: absolute;\n top: 1em;\n left: 13.25em;\n font-size: 8pt;\n color: #888;\n background-color: #e4e4e4;\n padding: 0;\n margin-top: -2px;\n border-top: 1px solid #aaa;\n border-bottom: 1px solid #330000;\n border-right: 1px solid #330000;\n border-left: 1px solid #aaa;\n}\n\n#contentWrapper .tabContentTags #popup hr {\n color: #ccc;\n}\n\nhr{\n color: black !important;\n}\n\n#contentWrapper .tabContentTags #popup a {\n display: block;\n color: #888;\n min-width: 8em;\n border: 0;\n margin: 0;\n height: 1.2em;\n}\n\n#contentWrapper .tabContentTags #popup a:hover {\n background-color: #e4e4e4;\n color: black;\n}\n\n#contentWrapper a.tab {\n font-weight: normal;\n display: inline;\n margin: 0px 1px; \n border:1px solid #aaa;\n border-bottom:none;\n}\n\n#contentWrapper a.tabSelected {\n background-color: #e6e6e6 !important;\n padding: 2px 4px 2px 4px;\n}\n\n#contentWrapper a.tabUnselected {\n background-color: #f3f3f3;\n padding: 2px 4px 0px 4px;\n}\n\n/*===========================================================================================*/\n/*===========================================================================================*/\n#sidebarTabs{\n margin: 0;\n padding: 0;\n}\n\n#contentWrapper .tabContents {\n background-color: #e6e6e6;\n border-bottom: solid #aaa 1px;\n}\n\n#contentWrapper .tabContents a.tiddlyLink, #contentWrapper .tabContents a.button{\n background-color: #e6e6e6;\n color: #922 !important;\n}\n\n#contentWrapper .tabContents a:hover{\n color: #b44 !important;\n}\n\n#contentWrapper .txtMoreTab a.tabUnselected {\n background-color: #e6e6e6;\n padding: 2px 4px 0px 4px;\n}\n\n#contentWrapper .txtMoreTab a.tabSelected {\n background-color: #ccc !important;\n padding: 2px 4px 2px 4px;\n}\n\n.txtMoreTab .tabContents {\n background-color: #ccc !important;\n border-bottom: solid #aaa 1px;\n}\n\n.txtMoreTab .tabContents a{\n background-color: transparent !important;\n}\n\n#licensePanel {\n padding: 0.5em 0.2em 0.5em 0.2em;\n}\n\n#licensePanel a {\n display: block;\n padding: 0.2em 0.2em 0.2em 0.2em;\n color: #555;\n}\n\n#licensePanel a:hover {\n text-decoration: none;\n color: #922;\n background-color: transparent;\n}\n\n#storeArea, #copyright {\n display: none;\n}\n\n#floater {\n font-size: 10pt;\n visibility: hidden;\n color: white;\n border: 1px solid #666;\n background-color: white;\n position: absolute;\n padding: 1em 1em 1em 1em;\n display:none;\n}\n\n@media print {\n\n#mainMenu {\n display: none;\n}\n\n#displayArea {\n margin: 1em 1em 0em 1em;\n}\n\n#sidebar {\n display: none;\n}\n\n}\n/*\n}}}\n*/</div>
<div tiddler="TagCloud" modified="200509301608" modifier="Pavel" tags="systemConfig [[Macro / Plugin]]">/*\n{{{\n*/\nversion.extensions.tagCloud = {major: 1, minor: 0 , revision: 1, date: new Date(2005,8,16)};\n//Created by Clint Checketts, contributions by Jonny Leroy and Eric Shulman\n// // source: http://15black.bluedepot.com/twtests/tagcloud.htm\n\nsetStylesheet(&quot;\s\n	.tagCloud span{height: 1.8em;margin: 3px;}\s\n	.tagCloud1{font-size: 1.2em;}\s\n	.tagCloud2{font-size: 1.4em;}\s\n	.tagCloud3{font-size: 1.6em;}\s\n	.tagCloud4{font-size: 1.8em;}\s\n	.tagCloud5{font-size: 1.8em;font-weight: bold;}&quot;,&quot;tagCloudsStyles&quot;\n);\n\nconfig.macros.tagCloud = {\n noTags: &quot;Тэгов нет.&quot;,\n tooltip: &quot;%1 записок помечено тэгом '%0'&quot;\n};\n\nconfig.macros.tagCloud.handler = function(place,macroName,params) {\n \nvar tagCloudWrapper = createTiddlyElement(place,&quot;div&quot;,null,&quot;tagCloud&quot;,null);\n\nvar tags = store.getTags();\nfor (t=0; t&lt;tags.length; t++) {\n  for (p=0;p&lt;params.length; p++) if (tags[t][0] == params[p]) tags[t][0] = &quot;&quot;;\n}\n\n if(tags.length == 0) \n   createTiddlyElement(tagCloudWrapper,&quot;span&quot;,null,null,this.noTags);\n //Findout the maximum number of tags\n var mostTags = 0;\n for (t=0; t&lt;tags.length; t++) if (tags[t][0].length &gt; 0){\n  if (tags[t][1] &gt; mostTags) mostTags = tags[t][1];\n }\n //divide the mostTags into 4 segments for the 4 different tagCloud sizes\n var tagSegment = mostTags / 4;\n\n  for (t=0; t&lt;tags.length; t++) if (tags[t][0].length &gt; 0){\n var tagCloudElement = createTiddlyElement(tagCloudWrapper,&quot;span&quot;,null,null,null);\n tagCloudWrapper.appendChild(document.createTextNode(&quot; &quot;));\n var theTag = createTiddlyButton(tagCloudElement,tags[t][0],this.tooltip.format(tags[t]),onClickTag,&quot;tagCloudtag tagCloud&quot; + (Math.round(tags[t][1]/tagSegment)+1));\n  theTag.setAttribute(&quot;tag&quot;,tags[t][0]);\n }\n\n};\n\n/*\n}}}\n*/</div>
<div tiddler="TiddlyWiki" modified="200509301632" modifier="Pavel" tags="Помощь">Собственно то, что перед вами и есть TiddlyWiki. Автор - Jeremy Ruston, http://www.tiddlywiki.com/. TiddlyWiki публикуется под BSD open source license.\n</div>
<div tiddler="ToolBar" modified="200509301613" modifier="Pavel" tags="systemConfig [[Macro / Plugin]]">/*\n{{{\n*/\nconfig.views.wikified.toolbarCloseOthers = {text: &quot;закрыть другие&quot;, tooltip: &quot;Закрыть все записки, кроме этой&quot;};\nconfig.views.wikified.toolbarNewHere = {text: &quot;новая&quot;, tooltip: &quot;Создать записку с тем же набором тэгов, что и у этой&quot;};\nconfig.views.wikified.toolbarCollapse = {text: &quot;свернуть&quot;, tooltip: &quot;Свернуть эту запискуr&quot;, toggleText: &quot;развернуть&quot;, toggleTooltip: &quot;Развернуть эту записку&quot;};\nconfig.views.editor.toolbarDuplicate = {text: &quot;дубликат&quot;, tooltip: &quot;Дублировать эту записку&quot;, suffix: &quot;Копия &quot;};\n\nwindow.onClickToolbarNewHere = function(e)\n{\n	if (!e) var e = window.event;\n	clearMessage();\n	if(this.parentNode.id) {\n		displayTiddler(this.parentNode,&quot;New Tiddler&quot;,2,null,null,false,false);\n		tagBox = document.getElementById(&quot;editorTagsNew Tiddler&quot;); \n		tagBox.value = this.parentNode.id.substring(7);\n	}\n	e.cancelBubble = true;\n	if (e.stopPropagation) e.stopPropagation();\n	return(false);\n}\n\nwindow.onClickToolbarDuplicate= function(e)\n{\n	if (!e) var e = window.event;\n	clearMessage();\n	if(this.parentNode.id) {\n\n	clearMessage();\n	var lingo = config.views\n	lingo = lingo.editor;\n	var thisSrc = document.getElementById(this.parentNode.id);\n	var thisTiddler = this.parentNode.id.substr(7);\n	var dupBody = document.getElementById(&quot;editorBody&quot; + thisTiddler).value;\n	var dupTitle = thisTiddler + lingo.toolbarDuplicate.suffix;\n	displayTiddler(thisSrc,dupTitle,2,null,null,false);\n	document.getElementById(&quot;editorBody&quot; + dupTitle).value = dupBody;\n	tagBox = document.getElementById(&quot;editorTags&quot;+dupTitle);\n	tagBox.value = document.getElementById(&quot;editorTags&quot;+ thisTiddler).value;\n\n	// If you want the original tiddler to close completely after you click 'duplicate,' then remove the slashes at the start of the next line\n	//closeTiddler(thisTiddler,false);\n       }\n	e.cancelBubble = true;\n	if (e.stopPropagation) e.stopPropagation();\n	return(false);\n}\n\nfunction onClickToolbarCollapse(e)\n{\n	if (!e) var e = window.event;\n	title = this.parentNode.id.substr(7);\n	if(title)\n		{\n		var viewerStatus = document.getElementById(&quot;viewer&quot; + title).style.display\n		var displayStyle;\n		var buttonText;\n		var buttonTooltip;\n		var lingo = config.views\n		lingo = lingo.wikified;\n		if(viewerStatus == &quot;none&quot;)\n			{\n			displayStyle = &quot;block&quot;;\n			buttonText = lingo.toolbarCollapse.text;\n			buttonTooltip = lingo.toolbarCollapse.tooltip;\n			}\n		else\n			{\n			displayStyle = &quot;none&quot;;\n			buttonText = lingo.toolbarCollapse.toggleText;\n			buttonTooltip = lingo.toolbarCollapse.toggleTooltip;\n			}\n		document.getElementById(&quot;viewer&quot; + title).style.display = displayStyle; \n		document.getElementById(&quot;footer&quot; + title).style.display = displayStyle; \n		this.innerHTML = buttonText;\n		this.title = buttonTooltip;\n		}\n}\n\nwindow.onClickToolbarCloseOthers = function(e)\n{\n	if (!e) var e = window.event;\n	clearMessage();\n	if(this.parentNode.id)\n		closeAllOtherTiddlers(this.parentNode.id.substr(7));\n	e.cancelBubble = true;\n	if (e.stopPropagation) e.stopPropagation();\n	return(false);\n}\n\nfunction closeAllOtherTiddlers(thisTitle)\n{\n	clearMessage();\n	var place = document.getElementById(&quot;tiddlerDisplay&quot;);\n	var tiddler = place.firstChild;\n	var nextTiddler;\n	while(tiddler)\n		{\n		nextTiddler = tiddler.nextSibling;\n		if(tiddler.id)\n			if(tiddler.id.substr(0,7) == &quot;tiddler&quot;)\n				{\n				var title = tiddler.id.substr(7);\n				if(!document.getElementById(&quot;editor&quot; + title) &amp;&amp; title != thisTitle)\n					place.removeChild(tiddler);\n				}\n		tiddler = nextTiddler;\n		}\n	window.scrollTo(0,0);\n}\n// Create a tiddler toolbar according to whether it's an editor or not\nwindow.createTiddlerToolbar = function(title,isEditor)\n{\nvar theToolbar = document.getElementById(&quot;toolbar&quot; + title);\nvar lingo = config.views;\nif(theToolbar)\n{\nremoveChildren(theToolbar);\ninsertSpacer(theToolbar);\nif(isEditor)\n{\n// Editor toolbar\nlingo = lingo.editor;\ncreateTiddlyButton(theToolbar,lingo.toolbarDone.text,lingo.toolbarDone.tooltip,onClickToolbarSave);\ninsertSpacer(theToolbar);\ncreateTiddlyButton(theToolbar,lingo.toolbarDuplicate.text,lingo.toolbarDuplicate.tooltip,onClickToolbarDuplicate);\ninsertSpacer(theToolbar);\ncreateTiddlyButton(theToolbar,lingo.toolbarCancel.text,lingo.toolbarCancel.tooltip,onClickToolbarUndo);\ninsertSpacer(theToolbar);\ncreateTiddlyButton(theToolbar,lingo.toolbarDelete.text,lingo.toolbarDelete.tooltip,onClickToolbarDelete);\n}\nelse\n{\n// Viewer toolbar\nlingo = lingo.wikified;\ncreateTiddlyButton(theToolbar,lingo.toolbarClose.text,lingo.toolbarClose.tooltip,onClickToolbarClose);\ninsertSpacer(theToolbar);\ncreateTiddlyButton(theToolbar,lingo.toolbarCloseOthers.text,lingo.toolbarCloseOthers.tooltip,onClickToolbarCloseOthers);\ninsertSpacer(theToolbar);\ncreateTiddlyButton(theToolbar,lingo.toolbarCollapse.text,lingo.toolbarCollapse.tooltip,onClickToolbarCollapse,&quot;toolbarCollapse&quot;);\ninsertSpacer(theToolbar);\ncreateTiddlyButton(theToolbar,lingo.toolbarEdit.text,lingo.toolbarEdit.tooltip,onClickToolbarEdit);\ninsertSpacer(theToolbar);\ncreateTiddlyButton(theToolbar,lingo.toolbarPermalink.text,lingo.toolbarPermalink.tooltip,onClickToolbarPermaLink);\ninsertSpacer(theToolbar);\ncreateTiddlyButton(theToolbar,lingo.toolbarReferences.text,lingo.toolbarReferences.tooltip,onClickToolbarReferences);\ninsertSpacer(theToolbar);\ncreateTiddlyButton(theToolbar,lingo.toolbarNewHere.text,lingo.toolbarNewHere.tooltip,onClickToolbarNewHere);\ninsertSpacer(theToolbar);\n}\n}\n}\n\n/*\n}}}\n*/</div>
<div tiddler="WikiWord" modified="200509291846" modifier="Pavel" tags="Помощь">WikiWord - способ записи названий записок. Его суть в том, что название должно начинаться с заглавной буквы и содержать еще как минимум одну заглавную внутри себя. Например МихаилПетров, ОбильнаАфрикаБананом. Если так озаглавить записку, то потом ссылаться на нее можно, просто набрав это слово, без дополнительных символов форматирования.</div>
<div tiddler="Все записи" modified="200509301639" modifier="Pavel" tags="">&lt;&lt;list all&gt;&gt;</div>
<div tiddler="Все тэги" modified="200509301556" modifier="Pavel" tags="">&lt;&lt;tagCloud&gt;&gt;</div>
<div tiddler="Как установить расширение" modified="200509301257" modifier="Pavel" tags="Помощь">Вы можете самостоятельно устанавливать новые макросы (подстановка текста), плагины (расширение функциональности), стили и переводы на другие языки.\n!!!Как установить плагин, макрос или перевод\n№ Скопируйте в буфер обмена текст плагина (код программы).\n№ Создайте новую записку и дайте ей соответствующее имя.\n№ Вставьте текст в тело записки.\n№ Пометьте записку тэгом ''systemConfig''.\n№ Сохраните записку.\n№ Сохраните TiddlyWiki.\n№ Нажмите в браузере кнопку ''Обновить''.\n\nВсе записки, помеченные тэгом ''systemConfig'' TiddlyWiki пытается интерпретировать как код программы и выполнить при загрузке. Таким образом, чтобы отключить расширение, не удаляя его, достаточно снять пометку тэгом ''systemConfig''.\n\n!!!Как установить стиль\nПовторите шаги, относящиеся к установке расширений, но только\n* назовите записку StyleSheet и никак иначе;\n* не помечайте ее тэгом ''systemConfig''.\n\nСоответственно, чтобы отключить, но не удалять стиль, нужно переименовать записку.\n\n----\nГде искать расширения - см. [[Ссылки]]</div>
<div tiddler="Наиболее интересные из сторонних макросов и плагинов" modified="200509301621" modifier="Pavel" tags="Помощь">Здесь коротко описаны расширения, включенные в этот файл.\n\n!!!OpenAll\nПозволяет открывать записки, помеченные определенным тэгом. В отличие от встроенного {{{tag}}} может предварительно закрывать все открытые записи, позволяет задавать надпись для кнопки, устанавливать лимит отображения (не более N записок) и изменять порядок сортировки на обратный.\n\nФормат {{{&lt;&lt;openAll &lt;тэг&gt; [параметры] &gt;&gt;}}}\n\nТэг обязателен, параметры опциональны и могут следовать в любом порядке.\n|!Параметр|!Описание|\n|close~AllFirst|Предварительно закрывает все открытые записки|\n|title:Текст|Надпись на кнопке|\n|limit:#| Замените # на число записок, которое вы хотите отобразить (по умолчанию 10000)|\n|reversOrder|Сортировать по заголовкам в обратном порядке|\n\nПример: {{{&lt;&lt;openAll systemConfig closeAllFirst &quot;title:Системные настройки&quot;&gt;&gt;}}}\n&lt;&lt;openAll systemConfig closeAllFirst &quot;title:Системные настройки&quot;&gt;&gt;\n\n!!!PreView\nРедактирование с одновременным просмотром результата. Понятно, тормозит, но иногда очень полезно. Включить можно в опциях.\n\n!!!ToolBar\nДобавляет к каждой записке кнопки:\n* закрыть другие - все записки, кроме текущей закрываются\n* новая - создает новую записку с тем же набором тэгов, что и у текущей\n* свернуть - позволяет свернуть записку до заголовка и развернуть обратно\n* дубликат - создает копию записки\n\n!!!TagCloud\n&quot;Облако тэгов&quot;, отображает все тэги, причем размер шрифта каждого тэга зависит от того, как много записок помечены этим тэгом.\nФормат: {{{&lt;&lt;tagCloud&gt;&gt;}}}\n\n----\n//Примечание: информацию об авторстве см. в тексте расширений.//</div>
<div tiddler="Начало" modified="200509301612" modifier="Pavel" tags="">Перед вами адаптированная версия [[TiddlyWiki|http://www.tiddlywiki.com]].\nЯ взял на себя смелость процитировать Дениса Балуева (http://lifehack.ru):\n&lt;&lt;&lt;\nПеред вами - русифицированная версия файла TiddlyWiki, универсальной записной книжки\nдля хранения самой разнообразной информации. Уникальность TiddlyWiki в том, что он умеет редактировать\nсам себя, добавляя в свой файл новые записи. Поэтому один-единственный файл может содержать в себе целый сайт! Кроме того, такой файл можно носить на флэш-диске и редактировать свои записи на любом компьютере, имеющим интернет-браузер. Удобно? Да не то слово!\n\nКлючевым понятием TiddlyWiki является так называемый Tiddler - Записка. Записки можно создавать,\nпросматривать, редактировать и удалять. Вся информация внутри TiddlyWiki хранится внутри этих записок.\nTiddlyWiki поддерживает технологию Wiki, что позволяет с легкостью редактировать просматриваемые\nзаписки и создавать связи между ними.\nКаждую запись пожно пометить одним или несколькими тэгами. Удобство этой опции сложно переоценить. Например, записке &quot;Автомеханик Бородулин Иван Владимирович, телефон 123-456&quot; можно присвоить два тэга - &quot;Машина&quot; и &quot;Контакты&quot;. - в дальнейшем искать такую запись можно будет по обоим тэгам.\nTiddlyWiki является гибко настраиваемой системой, причем большинство модификаций не затрагивают основной код файла, а записываются в тех же записках, помеченных тэгами systemTiddlers и systemConfig. Хотите переделать главное меню, находящееся на левой панели? Откройте записку MainMenu и редактируйте ее по своему усмотрению.\nРабота с TiddlyWiki включает в себя множество &quot;вкусных&quot; опций, большинство из которых описано на сайте TiddlyWiki: http://www.tiddlywiki.com\n&lt;&lt;&lt;\nЛучше не скажешь.\n\nДанная сборка основана на TiddlyWiki &lt;&lt;version&gt;&gt;. Изменения, внесенные мной:\n* дополнительные правила форматирования часто используемых элементов, призванные облегчить работу на русской раскладке клавиатуры\n* руссификация интерфейса (перевод содержится непосредственно в программном коде файла, а не в отдельной записке)\n* русская справка\n\nМои благодарности:\nJeremy Ruston за идею и реализацию\n Денису Балуеву за ссылку и  описание, мимо которых я не смог пройти\nвам за внимание.\n\nПавел Рындин\ne-mail: ryndin [at] gmail.com</div>
<div tiddler="Некоторые встроенные макросы" modified="200509301311" modifier="Pavel" tags="Помощь">!!!Timeline {{{&lt;&lt;timeline&gt;&gt;}}}\nВыводит записи в хронологическом порядке.\n\n!!!Сегодняшняя дата: {{{&lt;&lt;today&gt;&gt;}}}\nРезультат: &lt;&lt;today&gt;&gt;\n\n!!!Записки, помеченные тэгом: {{{&lt;&lt;tag systemConfig&gt;&gt;}}}\nРезультат: &lt;&lt;tag systemConfig&gt;&gt;\n\n!!!Новая дневниковая записка: {{{&lt;&lt;newJournal &quot;DD MMM YYYY, hh:mm&quot;&gt;&gt;}}}\nРезультат: &lt;&lt;newJournal &quot;DD MMM YYYY, hh:mm&quot;&gt;&gt;\n*DDD - день недели\n*DD - число, 0DD - добавлять лидирующий ноль\n*MMM - название месяца\n*MM - номер месяца, 0MM - добавлять лидирующий ноль\n*YYYY - год (четыре цифры), YY - две цифры\n*hh - часы\n*mm - минуты\n*ss - секунды\n\n!!!Включение записки: {{{&lt;&lt;tiddler MainMenu&gt;&gt;}}}\nВставляет текст другой записки в эту. ++Внимание!++ На данный момент нет защиты от бесконечных  циклов в случае включений &quot;по замкнутому кругу&quot;.\n\n\n&lt;&lt;tiddler MainMenu&gt;&gt;\n\n\n!!!Слайдер: {{{&lt;&lt;slider chkTestSlider OptionsPanel Настройки &quot;То же, что и 'опции'&quot;&gt;&gt;}}}\nРезультат: &lt;&lt;slider chkTestSlider OptionsPanel Настройки &quot;То же, что и 'опции'&quot;&gt;&gt;\nПараметры по порядку:\n№ имя &quot;cookie&quot; для сохранения состояния слайдера\n№ имя заметки, содержащей текст слайдер (это может быть любая заметка)\n№ заголовок ссылки\n№ всплывающая подсказка\n\n!!!Вкладки \n{{{\n&lt;&lt;tabs txtFavourite\nМеню &quot;Главное меню&quot; MainMenu\nОпции &quot;Опции&quot; SideBarOptions\n&gt;&gt;\n}}}\nРезультат:\n&lt;&lt;tabs txtFavourite\nМеню &quot;Главное меню&quot; MainMenu\nОпции &quot;Опции&quot; SideBarOptions\n&gt;&gt;\n----\n//Конечно, здесь описаны не все существующие макросы.//</div>
<div tiddler="Песочница" modified="200509301310" modifier="Pavel" tags="Помощь">Место для экспериментов с форматированием.\n\n</div>
<div tiddler="Расширения" modified="200509301628" modifier="Pavel" tags="Помощь">Макросы позволяют вставлять в записку автоматически сгенерированный текст. Вызов макроса записывается между двойными угловыми скобками:\n{{{\n&lt;&lt;имя_макроса параметры_если_нужны&gt;&gt;\n}}}\nВ режиме просмотра эта конструкция будет заменена на текст, генерируемый макросом.\nВ версии 1.2.34 ~TiddlyWiki уже включены некоторые макросы, кроме того можно устанавливать дополнительно макросы сторонних авторов или написанные вами.\n\nПлагины расширяют функциональность TiddlyWiki. Это может быть как дополнительная кнопка, так и совершенно новые возможности, вроде использования TiddlyWiki в качестве почтового клиента.\n\n* [[Некоторые встроенные макросы]]\n* [[Наиболее интересные из сторонних макросов и плагинов]]\n* [[Как установить расширение]]</div>
<div tiddler="Системные записки" modified="200509301415" modifier="Pavel" tags="Помощь">В TiddlyWiki существуют специальные записки, которые служат для настройки системы.\n* записки, помеченные тэгом ''systemConfig'' - содержат программный код расширений, исполняемый при загрузке\n* SiteUrl - адрес сайта, на котором размещен данный файл (имеет смысл при размещении в Интернете)\n* SiteTitle - первая часть заголовка страницы\n* SiteSubtitle - вторая часть заголовка страницы\n* MainMenu - содержимое этой записки отображается в меню (обычно слева, но местоположение может зависеть от стиля)\n* OptionsPanel - отображается в слайдер &quot;Опции&quot; (обычно справа)\n* AdvancedOptions - содержит дополнительные настройки\n* DefaultTiddlers - содержит перечень записок, которые будут открыты сразу после загрузки</div>
<div tiddler="Советы" modified="200509301456" modifier="Pavel" tags="Помощь">* после первой загрузки сразу измените в [[опциях|OptionsPanel]] имя пользователя на свое\n* возможность использовать внедренный HTML позволяет копировать с других сайтов текст вместе с оформлением\n* вы можете скопировать в режиме просмотра записку в MS Word, сохранив таким образом ее оформление для печати или вставки в документ; учтите только, что:\n** это единственный пункт, по которому ~FireFox проигрывает; для этой операции лучше подойдет Explorer\n** скопированная записка будет оформлена не текущим стилем, а тем, что содержится в программном коде (его вы можете видеть если у вас нет записки, озаглавленной StyleSheet); впрочем, таблица останется таблицей\n** если после вставки в MS Word вы видите пустой лист, включите отображение непечатаемых символов: текст может быть отформатирован скрытым шрифтом (меняется там же, где все свойства шрифта)\n* активно используйте тэги, но следите, чтобы их не расплодилось слишком много\n* не забывайте про поиск\n* настройте MainMenu по своему усмотрению\n\n!!!Пользователям ~FireFox под Windows\nСледите, чтобы путь к вашему файлу не содержал пробелов, иначе ~FireFox не сможет сохранять изменения.\nПри первой попытке сохранения ~FireFox запрашивает у пользователя разрешение на эту операцию. Включите опцию &quot;Запомнить разрешение&quot; и нажмите OK. В дальнейшем вопросов не будет.\n\n!!!Пользователям MS Internet Explorer\nПри загрузке вам придется все время &quot;разрешать заблокированное содержимое&quot;. Если вы хотите избавиться хотя бы от лишних вопросов при сохранении изменений, сделайте следующее:\n* создайте текстовый фал с таким содержимым\n{{{\nREGEDIT4\n;This registry modification will open additional security zone in MS Internet Explorer\n\n[HKEY_CURRENT_USER\sSoftware\sMicrosoft\sWindows\sCurrentVersion\sInternet Settings\sZones\s0]\n&quot;Flags&quot;=dword:00000219\n}}}\nи расширением {{{.reg}}}\n* запустите его\n* откройте &quot;Свойства обозревателя&quot;, вкладка &quot;Безопасность&quot;\n* выберите появившуюся зону безопасности &quot;Мой компьютер&quot; и нажмите &quot;Уровень безопасности - Другой...&quot;\n* убедитесь, что в области, посвященной ~ActiveX все пункты отмечены как разрешенные\n* грязно выругайтесь и переходите на ~FireFox :)\n</div>
<div tiddler="Справка" modified="200509301615" modifier="Pavel" tags="Помощь">[[Советы]]\n[[Форматирование]]\n[[Расширения]]\n[[Системные записки]]\n\nВсе разделы: &lt;&lt;tag Помощь&gt;&gt;</div>
<div tiddler="Ссылки" modified="200509301528" modifier="Pavel" tags="">Все на английском, к сожалению.\n\n!!!TiddlyWiki\nhttp://www.tiddlywiki.com/\n\n!!!Плагины, стили и советы\nhttp://homes.jcu.edu.au/~ccscb/mptw/\nhttp://www.zRenard.com\nhttp://tiddlywikitips.com/\nhttp://www.elsdesign.com/tiddlywiki</div>
<div tiddler="Форматирование" modified="200509301624" modifier="Pavel" tags="Помощь">Переведено и адаптировано с http://webpages.charter.net/one_each/\n----\n&gt;This is a simple cheat sheet gleened from the [[TiddlyWiki Tutorial|http://www.blogjones.com/TiddlyWikiTutorial.html]]. \n\n!Форматирование текста\n//Данный файл содержит дополнительные возможности форматирования, созданные с целью облегчить жизнь русскоязычным пользователям. Для таких возможностей в качестве примера использовано слово &quot;альтернатива&quot;.//\n\n|!Пример|!Реализация|\n|''жирный''|{{{''жирный''}}}|\n|&gt;|^^//Выше не двойная кавычка, а две одинарных//^^|\n|++альтернатива++|{{{++альтернатива++}}}|\n|==зачеркнутый==|{{{==зачеркнутый==}}}|\n|__подчеркнутый__|{{{__подчеркнутый__}}}|\n|//курсив//|{{{//курсив//}}}|\n|^^надстрочный^^|{{{^^надстрочный^^}}}|\n|~~подстрочный~~|{{{~~подстрочный~~}}}|\n|@@color(green):цветной@@|{{{@@color(green):цветной@@}}}|\n|@@bgcolor(green):фон@@|{{{|@@bgcolor(green):фон@@}}}|\n|@@выделение@@|{{{@@выделение@@}}}|\n|{{{моноширинный}}}|{{{{{{моноширинный}}}}}}|\n|~ОтменитьWikiWord|{{{~ОтменитьWikiWord}}}|\n|&gt;|^^//Что такое WikiWord//^^|\n|[[ссылка]]|{{{[[ссылка]]}}}|\n|(-альтернатива-)|{{{(-альтернатива-)}}}|\n|[[внешняя ссылка|куда-то]]|{{{[[внешняя ссылка|куда-то]]}}}|\n|(-альтернатива|куда-то-)|{{{(-альтернатива|куда-то-)}}}|\n\n!блок моноширинного текста\n{{{\n {{{\nпример\n }}}\n}}}\n{{{\nпример\n}}}\n\n!Горизонтальная линия\n{{{----}}}\n----\n\n!Списки\n{{{\n* Начало\n* Середина\n** Середина 1\n** Середина 2\n}}}\n* Начало\n* Середина\n** Середина 1\n** Середина 2\n\n!Нумерованный список\n{{{\n# Начало\n# Середина\n## Середина 1\n## Середина 2\n}}}\nАльтернатива\n{{{\n№ Начало\n№ Середина\n№№ Середина 1\n№№ Середина 2\n}}}\n# Начало\n# Середина\n## Середина 1\n## Середина 2\n\n!Изображение\n{{{\n[img[замещающий текст|image URL]]\n}}}\n\n!Таблицы\nСтрока таблицы должна начинаться с вертикальной черты (|).\n{{{\n|Закончите строку латинской с, чтобы создать название таблицы|c\n|!Для заголовка &quot;!&quot; сразу после вертикальной черты.|!Заголовок2|!Заголовок3|\n|строка1 столбец1|строка1 столбец2|строка1 столбец3|\n|&gt;|&gt;|Объединение столбцов - знак &quot;больше&quot; ( &gt;)|\n|Объединение строк - знак &quot; ~&quot;|&gt;| Пробел выравнивает вправо|\n|~|&gt;| Пробелы с обеих сторон центруют |\n|&gt;|&gt;|bgcolor(green):Цвет фона bgcolor(цвет):|\n}}}\n\n|Закончите строку латинской с, чтобы создать название таблицы|c\n|!Для заголовка &quot;!&quot; сразу после вертикальной черты.|!Заголовок2|!Заголовок3|\n|строка1 столбец1|строка1 столбец2|строка1 столбец3|\n|&gt;|&gt;|Объединение столбцов - знак &quot;больше&quot; ( &gt;)|\n|Объединение строк - знак &quot; ~&quot;|&gt;| Пробел выравнивает вправо|\n|~|&gt;| Пробелы с обеих сторон центруют |\n|&gt;|&gt;|bgcolor(green):Цвет фона bgcolor(цвет):|\n\n\n\n!Цитаты\n{{{\n&lt;&lt;&lt;\n&quot;Beware the Jabberwock, my son!\nThe jaws that bite, the claws that catch!\nBeware the Jubjub bird, and shun\nThe frumious Bandersnatch!&quot;\n&lt;&lt;&lt;\n}}}\n&lt;&lt;&lt;\n&quot;Beware the Jabberwock, my son!\nThe jaws that bite, the claws that catch!\nBeware the Jubjub bird, and shun\nThe frumious Bandersnatch!&quot;\n&lt;&lt;&lt;\n\n{{{\n&gt;У попа была собака\n&gt;...\n&gt;На могиле написал:\n&gt;&gt;У попа была собака\n&gt;&gt;...\n&gt;&gt;На могиле написал:\n}}}\n&gt;У попа была собака\n&gt;...\n&gt;На могиле написал:\n&gt;&gt;У попа была собака\n&gt;&gt;...\n&gt;&gt;На могиле написал:\n\n!Заголовки\n{{{\n!Заголовок\n!!Подзаголовок\n!!!Подзаголовок 2\n!!!!Подзаголовок 3\n!!!!!Подзаголовок 4\n}}}\n!Заголовок\n!!Подзаголовок\n!!!Подзаголовок 2\n!!!!Подзаголовок 3\n!!!!!Подзаголовок 4\n\n!Внедренный HTML\n{{{\n&lt;html&gt;\nС недавних пор в &lt;a href=&quot;http://www.tiddlywiki.com/&quot;&gt;TiddlyWiki&lt;/a&gt; появилась возможность использовать &lt;b&gt;внедренный HTML&lt;/b&gt;\n&lt;/html&gt;\n}}}\n&lt;html&gt;\nС недавних пор в &lt;a href=&quot;http://www.tiddlywiki.com/&quot;&gt;TiddlyWiki&lt;/a&gt; появилась возможность использовать &lt;b&gt;внедренный HTML&lt;/b&gt;\n&lt;/html&gt;</div>
		</div>
	</body>
</html>
